美文网首页
Numpy数据分析基本, since 2022-05-29

Numpy数据分析基本, since 2022-05-29

作者: Mc杰夫 | 来源:发表于2022-05-29 13:46 被阅读0次

    [toc]

    注:内容来自Numpy基础训练70题

    常用命令集合

    (2022.05.30)

    • 中值:np.median
    • 均值:np.mean
    • 极大/小值:np.max(arr, axis=0)/np.min/np.amax,axis=0代表求arr中按列的最值,axis=1是按行的最值
    • 标准差:np.std
    • 分位点:np.percentile
    • 改变数组尺寸:np.reshape(n, -1)则变成n行,np.reshape(-1, m)则变成m列,np.reshape(n, m)`则n行m列
    • 判断值为空:np.isnan
    • 列间相关系数:np.corrcoef(arr1, arr2)
    • 统计值的个数:np.unique(arr, return_counts=True, return_index=True),return_counts=True返回每个值的counts,return_index=True则返回每个独一无二元素第一次出现的index
    • 找出符合条件的索引:np.where
    • 找出符合条件的索引,并用新值替换:np.where(condition, new_value, arr)
    • 数组的堆叠:np.vstack按纵向堆叠,np.hstack横向堆叠
    • 数组的复制:np.repeat(arr, n)对arr按元素复制n次,结果如[a1, a1, a1,..., a2, a2, ...],np.tile(arr, n)对arr按块复制n次
    • 最大值的索引:np.argmax(arr)
    • 排序后的索引:np.argsort(arr),对arr做排序,返回arr中各元素的索引在排序后的位置顺序,即arr[np.argsort(arr)]将返回一个从小到大排序的序列
    • 两数组的相同值和不同值:np.intersect1dnp.setdiff1d
    • 多维数组中行、列的转换:见下文
    • 范围内的所有值:np.clip(arr, a_min=m, a_max=n)返回arr中在m和n之间的所有值,包括m、n本身
    • 创建0序列:np.zeros((n, m))创建n行m列的0序列
    • 满足条件的元素位置index:np.argwhere(arr>x),arr这个array中大于x的元素index,如果arr是二维array,则每个元素的index用[n, m]这样的形式表示
    • 展开多维数组array:np.ravelnp.flatten,二者都用于将多维数组展开成一维数组,但是np.ravel返回的是对原始数组的引用(reference),也就是修改展开后的数组的值可能会影响初始数组对应值,并且创建时不开辟新的内存空间,速度更快;np.flatten返回的是一个初始数组的copy,修改展开后的数组值不会影响初始数组对应值,因其创建了新的内存空间,速度弱于np.ravel
    • 做差分:np.diff(arr, axis=0)如果arr是一维,则无须指定axis,返回arr的差分序列,如果arr为多维,指定axis=0则沿着列做差分,axis=1沿行做差分
    • 将标量函数处理为矢量函数:np.vectorize
    • 沿着行/列做复杂操作:np.apply_along_axis(func, axis, arr, *args, **kwargs),axis=0沿着列向操作,axis=1沿行操作。

    案例

    (2022.05.29 Sun)

    • 生成一个一维数组,从list
    >> import numpy as np
    >> a = np.array([i for i in range(10)])
    >> a
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    • 生成一个2*3的bool矩阵,都是1,或都是0
    >> np.ones([2,3], dtype=bool)
    array([[ True,  True,  True],
           [ True,  True,  True]])
    >> np.zeros([2, 3], dtype=float)
    array([[0., 0., 0.],
           [0., 0., 0.]])
    

    其中dtype字段也可以指定其他类型,如intfloatstr等。

    • 数组中元素按条件的筛选,返回元素本身
    >> tmp = a[a%2==1]
    >> tmp
    array([1, 3, 5, 7, 9])
    
    • 数组中元素按条件筛选,返回元素index,np.where
    >> a = np.array([t for t in range(9,-1,-1)])
    >> a
    array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
    >> np.where(a%2==1)
    (array([0, 2, 4, 6, 8]),)
    
    • 替换原数组中符合条件的值为新值,原数组不变,np.where
    >> a = np.array([t for t in range(9,-1,-1)])
    >> out = np.where(a%3==1, -1, a)
    >> out
    array([ 9,  8, -1,  6,  5, -1,  3,  2, -1,  0])
    
    • 改变数组尺寸,变成n行,arr.reshape(n, -1)
    >> a = np.array([t for t in range(12, 0, -1)])
    >> a.reshape(3, -1)
    array([[12, 11, 10,  9],
           [ 8,  7,  6,  5],
           [ 4,  3,  2,  1]])
    

    可以严格指定转换成n行m列,如果只是指定换成n行或m列,则列或行的标识写成-1即可。如转换成m列,则写成arr.reshape(-1, m)

    • 数组的堆叠,分为垂直堆叠和横向堆叠,vstackhstack
    >> a = np.array([t for t in range(12, 0, -1)])
    >> ares = a.reshape(4, -1)
    >> a1, a2 = ares[:2], ares[2:]
    >> a1
    array([[12, 11, 10],
           [ 9,  8,  7]])
    >> a2
    array([[6, 5, 4],
           [3, 2, 1]])
    >> np.hstack([a1, a2])
    array([[12, 11, 10,  6,  5,  4],
           [ 9,  8,  7,  3,  2,  1]])
    
    • 数组的复制,按元素复制和按块(tile)复制,np.repeatnp.tile
    >> a1[0]
    array([12, 11, 10])
    >> np.repeat(a1[0], 3)
    array([12, 12, 12, 11, 11, 11, 10, 10, 10])
    >> np.tile(a1[0], 3)
    array([12, 11, 10, 12, 11, 10, 12, 11, 10]) 
    
    • 返回两个数组的相同值/相同值的indexnp.intersect1d
    >> a
    array([12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1])
    >> atrun = np.array([t for t in range(12,6,-1)])
    >> atrun
    array([12, 11, 10,  9,  8,  7])
    >> np.intersect1d(a, atrun)
    array([ 7,  8,  9, 10, 11, 12])
    >> np.intersect1d(a, atrun, return_indices=True)
    (array([ 7,  8,  9, 10, 11, 12]), array([5, 4, 3, 2, 1, 0]), array([5, 4, 3, 2, 1, 0]))
    
    • 返回两个数组的不同值np.setdiff1d(a, b),注意该指令返回第一个参数a中不同于b的值
    >> np.setdiff1d(a, atrun)
    array([1, 2, 3, 4, 5, 6]
    >> np.setdiff1d(atrun, a)
    array([], dtype=int64)
    
    • 返回两个数组相同元素的index,np.index
    >> atrun = np.tile(atrun, 2) #保持两个数组维度相同
    >> np.where(a==atrun)
    (array([0, 1, 2, 3, 4, 5]),)
    
    • 筛选符合条件的元素index,np.where
    >> a = np.array([t for t in range(12, 0, -1)])
    >> np.where((a%2==1)&(a%3==1)) # 条件加括号
    (array([ 5, 11]),)
    
    • 处理标量函数在两个数组上运行,np.vectorize
    >> f = lambda x, y: x if x>y else y
    >> fv = np.vectorize(f, otypes=[float])
    >> fv(a,at)
    array([12., 11., 10.,  9.,  8.,  7., 12., 11., 10.,  9.,  8.,  7.])
    
    • 转换二维数组的行/列
    >> a1
    array([[12, 11, 10],
           [ 9,  8,  7]])
    >> a1[:,[1, 0, 2]] # 转换第0和1列
    array([[11, 12, 10],
           [ 8,  9,  7]])
    >> a1[[1,0], :] # 转换第0和1行
    array([[ 9,  8,  7],
           [12, 11, 10]])
    

    进一步的,反转二维数组的行/列

    >> a1[:, ::-1] #反转列
    array([[10, 11, 12],
           [ 7,  8,  9]])
    >> a1[::-1, :] # 反转行
    array([[ 9,  8,  7],
           [12, 11, 10]])
    
    • 设置打印和显示数组的方式,np.set_printoptions,其中可配置的参数包括precision=3保留3位小数,suppress=True大/小数字强制不使用科学计数法,threshold=6长数组显示/打印元素的数量默认1000无限长可使用np.inf,等
    >> np.set_printoptions(precision=3, suppress=True, threshold=1000)
    >> print(a)
    [12 11 10  9  8  7  6  5  4  3  2  1]
    

    (2022.05.30 Mon)
    找出空值元素index

    >> url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
    >> iris = np.genfromtxt(url, delimiter=',', dtype='object')
    >> sepallength = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0])
    >> sepal_normalised = (sepallength-sepallength.min()) /(sepallength.max()-sepallength.min())
    >> sepal_normalised[:10]
    array([0.22222222, 0.16666667, 0.11111111, 0.08333333, 0.19444444,
           0.30555556, 0.08333333, 0.19444444, 0.02777778, 0.16666667])
    >> np.percentile(sepallength, q=[5,95])
    array([4.6  , 7.255])
    >> nan_index = np.random.randint(10, size=5)
    >> nan_index
    array([0, 5, 8, 4, 9])
    >> sepallength[nan_index] = np.nan
    >> sepallength[:15]
    array([nan, 4.9, 4.7, 4.6, nan, nan, 4.6, 5. , nan, nan, 5.4, 4.8, 4.8,
           4.3, 5.8])
    >> np.where(np.isnan(sepallength))
    (array([0, 4, 5, 8, 9]),)
    

    选sepallength中的非零值成为新的array。可以看到新array的前10项和设置空值的sepallength的前15项中的非零项值相同,排序相同。

    >> np.isnan(sepallength).any() # 查看sepallength中是否有空值
    True
    >> sepal_nonzero = np.array(sepallength[np.where(~np.isnan(sepallength))])
    >> sepal_nonzero[:10]
    array([4.9, 4.7, 4.6, 4.6, 5. , 5.4, 4.8, 4.8, 4.3, 5.8])
    

    将空值设为-1

    sepal_new = np.where(np.isnan(sepallength), -1, sepallength)
    

    统计该序列中各个值的个数

    >> tuni = np.unique(sepallength, return_counts=True, return_index=True)
    >> tuni # [0]是unique values,[1]是unique values首次出现的index,[2]是unique values的counts
    (array([4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5. , 5.1, 5.2, 5.3, 5.4, 5.5,
            5.6, 5.7, 5.8, 5.9, 6. , 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8,
            6.9, 7. , 7.1, 7.2, 7.3, 7.4, 7.6, 7.7, 7.9, nan, nan, nan, nan,
            nan]),
     array([ 13,  38,  41,   3,   2,  11,   1,   7,  17,  27,  48,  10,  33,
             64,  15,  14,  61,  62,  63,  68,  56,  51,  54,  58,  65,  76,
             52,  50, 102, 109, 107, 130, 105, 117, 131,   0,   4,   5,   8,
              9]),
     array([1, 2, 1, 4, 2, 5, 5, 9, 8, 4, 1, 5, 7, 6, 8, 7, 3, 6, 6, 4, 9, 7,
            5, 2, 8, 3, 4, 1, 1, 3, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1]))
    

    找出该序列中第n大的数字

    >> tuni_nonzero = tuni[0][tuple(np.where(~np.isnan(tuni[0])))]
    >> tuni_nonzero[-3] # 第3大的数字
    7.6
    

    找出出现频率最高的数字

    >> ind = np.argmax(tuni[1]) # 在计数序列中找到最大值的索引
    >> tuni[0][ind] # 找出出现频率最高的值
    5.0
    

    找出arr中最大的前5个数字

    >> arr = np.random.randint(100, size=10)
    >> arr
    array([29, 67, 27, 37, 79, 88,  7, 99, 81, 93])
    >> arr[np.argsort(arr)[-5:]]
    array([79, 81, 88, 93, 99])
    

    找出二维arr2中大于1的数字的位置index

    >> arr2= np.array([[3,2,1],[4,5,7]])
    >> np.argwhere(arr2>2)
    array([[0, 0],
           [1, 0],
           [1, 1],
           [1, 2]])
    

    展开二维数组。结果中还可以看到np.ravelnp.flatten的差别。

    >> arr_ravel = arr2.ravel()
    >> arr_ravel[3] = 198
    >> arr_ravel
    array([  3,   2,   1, 198,   5,   7])
    >> arr2
    array([[  3,   2,   1],
           [198,   5,   7]])
    >> arr_flatten = arr2.flatten()
    >> arr_flatten[-1] = 298
    >> arr2_flatten
    array([  3,   2,   1, 198,   5, 298])
    >> arr2
    array([[  3,   2,   1],
           [198,   5,   7]])
    

    对数组做差分

    >> arr = np.random.randint(100, size=10)
    >> arr
    array([54, 89, 78, 87, 34, 84, 31, 55, 19, 72])
    >> np.diff(arr)
    array([ 35, -11,   9, -53,  50, -53,  24, -36,  53])
    >> arr2= np.array([[3,2,1],[4,5,7],[98, 198, 298]])
    >> np.diff(arr2, axis=0)
    array([[  1,   3,   6],
           [ 94, 193, 291]])
    

    对二维数组做复杂操作

    >> arr2= np.array([[3,2,1],[4,5,7],[98, 198, 298]])
    >> f = lambda x: x[0]+x[-1] - x[1]
    >> np.apply_along_axis(f, 0, arr2) # 沿axis=0列方向,首尾相加减去中间值
    array([ 97, 195, 292])
    

    数组中某值的第n=3个重复项所在的index

    >> n = 3
    >> arr4= np.random.randint(4, size=10)
    >> arr4
    array([0, 3, 0, 1, 2, 0, 0, 1, 3, 1])
    >> np.where(arr4==0)
    (array([0, 2, 5, 6]),)
    >> np.where(arr4==0)[0][n]
    6
    

    计算序列的移动平均值。提示:使用np.cumsum计算累加项和,再减去平移n位的数组,得到的就是相邻n项的和。

    def moving_ave(arr, n):
        cs = np.cumsum(arr)
        cs[n:] = cs[n:] - cs[-n:]
        return cs[n-1:]/n
    >> n = 3
    >> arr4 = np.random.randint(5, size=10)
    >> arr4
    array([2, 4, 1, 2, 4, 0, 4, 3, 1, 1])
    >> moving_ave(arr4, n)
    array([2.33333333, 2.33333333, 2.33333333, 2.        , 2.66666667,
           2.33333333, 2.66666667, 1.66666667])
    

    (2022.06.25 Sat)
    当然,如果仅仅为计算移动平均,pandasDataFramerolling(n=value).sum()更加方便。

    相关文章

      网友评论

          本文标题:Numpy数据分析基本, since 2022-05-29

          本文链接:https://www.haomeiwen.com/subject/fdegprtx.html