1 numpy小记
70个NumPy分级练习题:用Python一举搞定机器学习矩阵运算
import numpy as np # 1. 替换满足条件的元素而不影响原始数组 arr = np.arange(10) out = np.where(arr%2==1, -1, arr) arr Out[4]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) out Out[5]: array([ 0, -1, 2, -1, 4, -1, 6, -1, 8, -1]) # 7. 获取两个数组元素匹配的索引号 a = np.array([1,2,3,2,3,4,3,4,5,6]) b = np.array([7,2,10,2,7,4,9,4,9,8]) np.where(a==b) Out[33]: (array([1, 3, 5, 7], dtype=int64),) # 9. 将处理标量的python函数在numpy数组上运行 maxx = lambda x,y: x if x>=y else y pair_max = np.vectorize(maxx, otypes=[float]) a = np.array([5,7,9,8,6,4,5]) b = np.array([6,3,4,8,9,7,1]) pair_max(a,b) Out[45]: array([6., 7., 9., 8., 9., 7., 5.]) # 18. 导入含有数字和文本的数据集,并保持的文本完整性 url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data" irirs_ld = np.genfromtxt(url, delimiter=',', dtype=None) # 21. 计算softmax值 def softmax(x): ex = np.exp(x-np.max(x)) return ex/ex.sum(axis=0) # 29. 概率抽样 # 暂定 # 33. 两个数组之间的欧氏距离 arr = np.arange(5) brr = np.arange(4,9) dist = np.linalg.norm(arr-brr) dist Out[176]: 8.94427190999916 # 38. 不连续的日期数组。通过填补缺失的日期,使其成为连续的日期序列 # 39. 一维数组arr,使用步长生成一个二维数组,窗口长度为4,步长为2 def gen_strides(arr, stride_len=5, windows_len=5): n_strides = ((arr.size-windows_len)//stride_len)+1 return np.array([arr[s:(s+windows_len)] for s in np.arange(0, n_strides*stride_len,stride_len)]) gen_strides(np.arange(15), stride_len=2, windows_len=4) Out[207]: array([[ 0, 1, 2, 3], [ 2, 3, 4, 5], [ 4, 5, 6, 7], [ 6, 7, 8, 9], [ 8, 9, 10, 11], [10, 11, 12, 13]])
2 移动平均值
cumsum :计算轴向元素累加和,返回由中间结果组成的数组
cumprod :计算轴向元素累乘积,返回由中间结果组成的数组
data = np.array([1] * 10)
acum = data.cumsum()
cump = acum.cumprod()
print(acum)
[ 1 2 3 4 5 6 7 8 9 10]
print(cump)
array([ 1, 2, 6, 24, 120, 720, 5040,
40320, 362880, 3628800])
# 37. 窗口大小为3的移动平均值
def moving_average(a, n=3):
ret = np.cumsum(a, dtype=float)
ret[n:] = ret[n:]-ret[:-n]
return ret[n-1:]/n
np.random.seed(100)
Z = np.random.randint(10, size=10)
Z
Out[191]: array([8, 8, 3, 7, 7, 0, 4, 2, 5, 2])
moving_average(Z, n=3).round(2)
Out[192]: array([6.33, 6. , 5.67, 4.67, 3.67, 2. , 3.67, 3. ])
3 第n个重复项的索引
# 36. 第n个重复项的索引
# 找出x中第1个重复n次的索引
arr = np.array([1,2,1,1,3,4,3,1,1,2,1,1,2])
n = 5
[ii for ii,kk in enumerate(arr) if kk==1][n-1]
Out[186]: 8
np.where(arr==1)[0][n-1]
Out[187]: 8
4 按列排序二维数组
# 31. 按列排序二维数组
arr = np.random.uniform(size=(3,4))
arr
Out[146]:
array([[0.54040458, 0.29679375, 0.1107879 , 0.3126403 ],
[0.45697913, 0.65894007, 0.25425752, 0.64110126],
[0.20012361, 0.65762481, 0.77828922, 0.7795984 ]])
arr[arr[:,1].argsort()]
Out[147]:
array([[0.54040458, 0.29679375, 0.1107879 , 0.3126403 ],
[0.20012361, 0.65762481, 0.77828922, 0.7795984 ],
[0.45697913, 0.65894007, 0.25425752, 0.64110126]])
5 pearsonr相关系数
# 25. 计算某两列的pearsonr相关系数
arr = np.random.uniform(size=(3,4))
arr
Out[114]:
array([[0.59884338, 0.60380454, 0.10514769, 0.38194344],
[0.03647606, 0.89041156, 0.98092086, 0.05994199],
[0.89054594, 0.5769015 , 0.74247969, 0.63018394]])
from scipy.stats.stats import pearsonr
corr,p_value = pearsonr(arr[:,0], arr[:,2])
corr
Out[117]: -0.432641494562719
6 唯一值的数量
# 27. 查找numpy数组中的唯一值的数量
arr = np.random.uniform(size=(3,4))
np.unique(arr, return_counts=True)
Out[121]:
(array([0.04486228, 0.14260031, 0.17808099, 0.23769421, 0.34019022,
0.35479561, 0.37625245, 0.50543143, 0.5928054 , 0.62994188,
0.9338413 , 0.94637988]),
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int64))
# 28. 将数值转换为分类(文本)数组
# 将iris_2d的花瓣长度(第3列)组成一个文本数组
# <3 -> '小'
# 3-5 -> '中'
# >=5 -> '大
from sklearn import datasets
iris = datasets.load_iris().data
petal_length_bin = np.digitize(iris[:,2].astype('float'), [0,3,5,10])
label_map = {1:'small', 2:'medium', 3:'large', 4:np.nan}
petal_length_cat = [label_map[x] for x in petal_length_bin]
petal_length_cat[:4]
Out[130]: ['small', 'small', 'small', 'small']
7 多个条件过滤numpy数组
# 24. 根据两个或多个条件过滤一个numpy数组
# 过滤具有arr(第3列)> 0.5和arr(第1列)<0.8的arr的行。
arr = np.random.uniform(size=(3,4))
arr
Out[110]:
array([[0.81622475, 0.27407375, 0.43170418, 0.94002982],
[0.81764938, 0.33611195, 0.17541045, 0.37283205],
[0.00568851, 0.25242635, 0.79566251, 0.01525497]])
condition = (arr[:,2]>0.5) & (arr[:,0]<0.8)
arr[condition]
Out[112]: array([[0.00568851, 0.25242635, 0.79566251, 0.01525497]])
8 堆叠数组操作
# 2. 垂直堆叠两个数组
a = np.arange(10).reshape(2,-1)
b = np.repeat(1,10).reshape(2,-1)
a
Out[10]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
b
Out[11]:
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
np.concatenate([a,b], axis=0)
Out[12]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
np.vstack([a,b])
Out[13]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
np.r_[a,b]
Out[14]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
# 3. 水平堆叠两个数组
np.concatenate([a,b], axis=1)
Out[15]:
array([[0, 1, 2, 3, 4, 1, 1, 1, 1, 1],
[5, 6, 7, 8, 9, 1, 1, 1, 1, 1]])
np.hstack([a,b])
Out[16]:
array([[0, 1, 2, 3, 4, 1, 1, 1, 1, 1],
[5, 6, 7, 8, 9, 1, 1, 1, 1, 1]])
np.c_[a,b]
Out[17]:
array([[0, 1, 2, 3, 4, 1, 1, 1, 1, 1],
[5, 6, 7, 8, 9, 1, 1, 1, 1, 1]])
9 提取范围内的所有数字
# 8. 提取给定范围内的所有数字
a = np.arange(15)
index = np.where((a>=5) & (a<=10))
a[index]
Out[36]: array([ 5, 6, 7, 8, 9, 10])
index = np.where(np.logical_and(a>=5, a<=10))
a[index]
Out[38]: array([ 5, 6, 7, 8, 9, 10])
10 交换数组行列
# 10. 交换2维numpy数组中的两个列
np.arange(9).reshape(3,3)[:,[1,0,2]]
Out[46]:
array([[1, 0, 2],
[4, 3, 5],
[7, 6, 8]])
# 11. 交换2维numpy数组中的两个行
np.arange(9).reshape(3,3)[[1,0,2], :]
Out[47]:
array([[3, 4, 5],
[0, 1, 2],
[6, 7, 8]])
11 反转2维数组行列
# 12. 反转2维数组的行
np.arange(9).reshape(3,3)[[1,0,2], :]
Out[51]:
array([[3, 4, 5],
[0, 1, 2],
[6, 7, 8]])
# 13. 反转2维数组的列
np.arange(9).reshape(3,3)[:,::-1]
Out[48]:
array([[2, 1, 0],
[5, 4, 3],
[8, 7, 6]])
12 数组打印
# 15. 打印三位小数的numpy数组
np.set_printoptions(3)
np.random.uniform(5,10,(5,3))
Out[59]:
array([[5.427, 6.768, 6.71 ],
[7.243, 6.434, 7.314],
[6.692, 8.417, 7.965],
[8.718, 5.061, 5.936],
[5.918, 8.064, 7.431]])
# 16. 使用科学记数法(如1e10)漂亮的打印数组rand_arr
np.random.seed(100)
np.set_printoptions(suppress=True)
rand_arr = np.random.random([3,3])/1e3
rand_arr
Out[68]:
array([[0.000543, 0.000278, 0.000425],
[0.000845, 0.000005, 0.000122],
[0.000671, 0.000826, 0.000137]])
# 17. 限制数组输出中打印元素的数量
np.set_printoptions(threshold=6)
arr = np.arange(15)
arr
Out[73]: array([ 0, 1, 2, ..., 12, 13, 14])
13 标准化一个数组至0到1之间
# 20. 标准化一个数组至0到1之间
arr = np.random.uniform(size=(3,4))
arr
Out[89]:
array([[0.88959857, 0.64348368, 0.66692863, 0.41213651],
[0.78437761, 0.75333385, 0.10293507, 0.7942196 ],
[0.82432451, 0.11447181, 0.30328525, 0.41767367]])
s_max,s_min = arr.max(axis=0),arr.min(axis=0)
(arr-s_min)/(s_max-s_min)
Out[91]:
array([[1. , 0.82805338, 1. , 0. ],
[0. , 1. , 0. , 1. ],
[0.37964781, 0. , 0.35523487, 0.01449204]])
14 缺失值相关
# 26. 找出数组是否有缺失的值
arr = np.random.uniform(size=(3,4))
np.isnan(arr).any()
Out[119]: False
# 34. 删除所有nan值
arr = np.array([1,2,3,np.nan,5,6,7,np.nan])
arr[~np.isnan(arr)]
Out[167]: array([1., 2., 3., 5., 6., 7.])
# 23. 数据集的5个随机位插入np.nan值
arr = np.random.uniform(size=(3,4))
i,j = np.where(arr)
np.random.seed(100)
arr[np.random.choice((i),5), np.random.choice((j),5)] = np.nan
arr
Out[103]:
array([[ nan, 0.57138137, 0.27694632, 0.06905881],
[0.25886229, nan, nan, 0.0125819 ],
[ nan, 0.06872554, nan, 0.28179248]])
np.where(np.isnan(arr))
Out[105]: (array([0, 1, 1, 2, 2], dtype=int64), array([0, 1, 2, 0, 2], dtype=int64))
15 数组交差集
# 5. 数组之间的共同元素
a = np.array([1,2,3,2,3,4,3,4,5,6])
b = np.array([7,2,10,2,7,4,9,4,9,8])
np.intersect1d(a,b)
Out[27]: array([2, 4])
# 6. 删除存在于另一个数组中的元素
a = np.array([1,2,3,4,5])
b = np.array([5,6,7,8,9])
np.setdiff1d(a,b)
Out[30]: array([1, 2, 3, 4])
16 数组产生
# 4. 生成自定义序列
a = np.array([1,2,3])
np.r_[np.repeat(a,3), np.tile(a,3)].reshape(2,-1)
Out[24]:
array([[1, 1, 1, 2, 2, 2, 3, 3, 3],
[1, 2, 3, 1, 2, 3, 1, 2, 3]])
# 14. 二维数组,以包含5到10之间的随机浮点数
rand_arr = np.random.randint(low=5, high=10, size=(5,3)) + np.random.random((5, 3))
rand_arr
Out[56]:
array([[5.37441948, 8.61709329, 8.24544657],
[6.79517054, 6.43953972, 5.01129723],
[9.662239 , 6.24575781, 6.51341089],
[8.01997704, 6.66118956, 8.18283188],
[8.02228762, 6.9609364 , 7.4676691 ]])
rand_arr = np.random.uniform(5,10, size=(5,3))
rand_arr
Out[58]:
array([[7.13046251, 7.4977751 , 8.55210656],
[7.9222628 , 5.7828763 , 9.57743131],
[9.13648012, 5.71533963, 9.18622945],
[5.94241285, 8.08918632, 9.32716147],
[5.75027771, 8.83210586, 8.3991677 ]])
17 元素查找
# 19. 从一维元组数组中提取特定的列
iris_2d = np.array([row.tolist()[:4] for row in irirs_ld])
iris_2d[:4]
Out[78]:
array([[5.1, 3.5, 1.4, 0.2],
[4.9, 3. , 1.4, 0.2],
[4.7, 3.2, 1.3, 0.2],
[4.6, 3.1, 1.5, 0.2]])
# 22. 找到数组的百分位的值
# 第5位和第95百分位的值
arr = np.random.uniform(size=(3,4))
np.percentile(arr, q=[5,95])
Out[94]: array([0.31394255, 0.87443495])
# 30. 获得数组中第二大的元素值
arr = np.random.uniform(size=(3,4))
np.unique(np.sort(arr))[-2]
Out[132]: 0.9570126003527981
# 32. 首次出现的值大于给定值的位置
arr = np.random.uniform(size=(3,4))
arr
Out[150]:
array([[0.61032815, 0.30900035, 0.69773491, 0.8596183 ],
[0.62532376, 0.98240783, 0.97650013, 0.16669413],
[0.02317814, 0.16074455, 0.92349683, 0.95354985]])
np.argmax(arr[:,2].astype('float') > 0.7)
Out[151]: 1
# 35. 一维数组所有局部最大值(或峰值)
arr = np.array([1,3,7,1,2,6,0,1])
doublediff = np.diff(np.sign(np.diff(arr)))
peak_locations = np.where(doublediff==-2)[0]+1
peak_locations
Out[180]: array([2, 5], dtype=int64)