[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.intersect1d
和np.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.ravel
和np.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
字段也可以指定其他类型,如int
,float
,str
等。
- 数组中元素按条件的筛选,返回元素本身
>> 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)
- 数组的堆叠,分为垂直堆叠和横向堆叠,
vstack
和hstack
>> 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.repeat
和np.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])
- 返回两个数组的相同值/相同值的index,
np.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.ravel
和np.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)
当然,如果仅仅为计算移动平均,pandas
中DataFrame
的rolling(n=value).sum()
更加方便。
网友评论