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

[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)