2. 广播机制
【重要】ndarray广播机制的两条规则
- 规则一:为缺失的维度补1
- 规则二:假定缺失元素用已有值填充
例1:
m = np.ones((2, 3))
a = np.arange(3)
求M+a
import numpy as np#导包 别名
#创建三行两列的数值0-10之间的随机数组
nd = np.random.randint(0,10,size = (3,2))
nd
array([[0, 6],
[8, 0],
[1, 4]])
#创建三行两列的数值0-10之间的随机数组
nd2 = np.random.randint(0,10,size = (3,2))
nd2
array([[9, 6],
[3, 9],
[7, 7]])
nd + nd2 #相同格式的随机数组相加是相同位置的彼此相加
array([[ 9, 12],
[11, 9],
[ 8, 11]])
#随机生成0-10 1行两列的随机数组
nd3 = np.random.randint(0,10,size = (1,2))
nd3
array([[3, 2]])
# 广播机制
# nd3,只有一行,nd有3行,nd3,复制了3份
nd + nd3 #不同格式的随机数组相加是先变成格式相同的再相加
array([[ 3, 8],
[11, 2],
[ 4, 6]])
# 广播机制
nd + 10 #与数值相加是每一个值都加上这个数值
array([[10, 16],
[18, 10],
[11, 14]])
nd4 = np.random.randint(0,10,size = (1,3))
nd4
array([[7, 4, 7]])
display(nd,nd4)#显示数组
array([[0, 6],
[8, 0],
[1, 4]])
array([[7, 4, 7]])
nd + nd4 #不能相加原因是数组结构不匹配
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-1faa5468f779> in <module>()
----> 1 nd + nd4
ValueError: operands could not be broadcast together with shapes (3,2) (1,3)
#将nd4转换成3行1列的数组就可以相加了
# 行和列都可以实现广播机制,前提:形状相似
nd4.reshape(3,1) + nd
array([[ 7, 13],
[12, 4],
[ 8, 11]])
例2:
a = np.arange(3).reshape((3, 1))
b = np.arange(3)
求a+b
习题
a = np.ones((4, 1))
b = np.arange(4)
求a+b
六、ndarray的排序
小测验:
使用以上所学numpy的知识,对一个ndarray对象进行选择排序。
def Sortn(x):
代码越短越好
#随机生成数值在0-150 =元素个数为20的随机数组
nd = np.random.randint(0,150,size = 20)
nd
array([106, 49, 13, 4, 8, 105, 103, 146, 34, 93, 9, 123, 126,
131, 109, 23, 99, 116, 120, 76])
#随机数组从小到大排序
#此种方法无返回值 会将原来的数值改掉 所以需要自己手动输出
nd.sort()
nd
array([ 4, 8, 9, 13, 23, 34, 49, 76, 93, 99, 103, 105, 106,
109, 116, 120, 123, 126, 131, 146])
nd = np.random.randint(0,150,size = 20)
nd
array([147, 70, 0, 126, 52, 143, 60, 18, 118, 106, 106, 40, 0,
42, 116, 35, 53, 32, 128, 147])
nd
array([147, 70, 0, 126, 52, 143, 60, 18, 118, 106, 106, 40, 0,
42, 116, 35, 53, 32, 128, 147])
# 有返回值,说明之前的对象没有更改,内存中创建了新的对象
np.sort(nd)
array([ 0, 0, 18, 32, 35, 40, 42, 52, 53, 60, 70, 106, 106,
116, 118, 126, 128, 143, 147, 147])
nd = np.random.randint(0,150,size = (5,6))
nd
array([[102, 92, 57, 24, 10, 50],
[ 77, 147, 62, 60, 82, 26],
[ 50, 88, 63, 142, 33, 49],
[136, 26, 80, 136, 23, 12],
[129, 68, 3, 1, 4, 83]])
#axis 轴
# axis =0 代表行
# axis = 1 代表列
np.sort(nd,axis=0)
#按行排序是说将[102, 92, 57, 24, 10, 50]看作一个整体,
#第一行第一个和第二行第一个 第三行第一个第四行第一个 .....从小到大排序
#第一行第二个和第二行第二个 第三行第二个.......进行从小到大排序
#.......
array([[ 50, 26, 3, 1, 4, 12],
[ 77, 68, 57, 24, 10, 26],
[102, 88, 62, 60, 23, 49],
[129, 92, 63, 136, 33, 50],
[136, 147, 80, 142, 82, 83]])
nd
array([[102, 92, 57, 24, 10, 50],
[ 77, 147, 62, 60, 82, 26],
[ 50, 88, 63, 142, 33, 49],
[136, 26, 80, 136, 23, 12],
[129, 68, 3, 1, 4, 83]])
np.sort(nd,axis = 1)
#按列排序
#第一列第一个数 第二列第一个数 第三列第一个数.....从小到大排序
#第二列第一个数 第二列第二个数 第二列第三个数......从小到达排序
#.......
array([[ 10, 24, 50, 57, 92, 102],
[ 26, 60, 62, 77, 82, 147],
[ 33, 49, 50, 63, 88, 142],
[ 12, 23, 26, 80, 136, 136],
[ 1, 3, 4, 68, 83, 129]])
nd3 = np.random.randint(0,150,size = (4,5,6))
nd3
array([[[ 45, 105, 149, 50, 121, 136],
[117, 41, 118, 22, 30, 114],
[131, 107, 40, 43, 141, 99],
[ 57, 44, 101, 113, 19, 71],
[ 53, 148, 122, 50, 66, 142]],
[[ 61, 142, 24, 21, 32, 77],
[ 13, 79, 112, 110, 66, 13],
[ 9, 1, 127, 68, 44, 120],
[144, 133, 17, 82, 68, 120],
[ 81, 59, 127, 11, 69, 74]],
[[ 15, 19, 105, 101, 0, 88],
[ 59, 115, 19, 93, 141, 125],
[143, 68, 4, 98, 9, 0],
[ 98, 80, 78, 86, 28, 116],
[ 32, 25, 126, 123, 127, 43]],
[[126, 50, 74, 127, 141, 44],
[111, 35, 121, 36, 40, 10],
[ 9, 38, 50, 119, 90, 22],
[116, 6, 26, 36, 110, 60],
[ 76, 149, 38, 108, 60, 77]]])
np.sort(nd3,axis = 2)
#多维按轴排序 关键区分哪个轴
#三维数组 [[[ ....]]] 最外层的轴是2 中间层的轴是1 里面的轴是0
np.sort(nd3,axis = -1)
array([[[ 45, 50, 105, 121, 136, 149],
[ 22, 30, 41, 114, 117, 118],
[ 40, 43, 99, 107, 131, 141],
[ 19, 44, 57, 71, 101, 113],
[ 50, 53, 66, 122, 142, 148]],
[[ 21, 24, 32, 61, 77, 142],
[ 13, 13, 66, 79, 110, 112],
[ 1, 9, 44, 68, 120, 127],
[ 17, 68, 82, 120, 133, 144],
[ 11, 59, 69, 74, 81, 127]],
[[ 0, 15, 19, 88, 101, 105],
[ 19, 59, 93, 115, 125, 141],
[ 0, 4, 9, 68, 98, 143],
[ 28, 78, 80, 86, 98, 116],
[ 25, 32, 43, 123, 126, 127]],
[[ 44, 50, 74, 126, 127, 141],
[ 10, 35, 36, 40, 111, 121],
[ 9, 22, 38, 50, 90, 119],
[ 6, 26, 36, 60, 110, 116],
[ 38, 60, 76, 77, 108, 149]]])
np.sort(nd3,axis = 1)
array([[[ 45, 41, 40, 22, 19, 71],
[ 53, 44, 101, 43, 30, 99],
[ 57, 105, 118, 50, 66, 114],
[117, 107, 122, 50, 121, 136],
[131, 148, 149, 113, 141, 142]],
[[ 9, 1, 17, 11, 32, 13],
[ 13, 59, 24, 21, 44, 74],
[ 61, 79, 112, 68, 66, 77],
[ 81, 133, 127, 82, 68, 120],
[144, 142, 127, 110, 69, 120]],
[[ 15, 19, 4, 86, 0, 0],
[ 32, 25, 19, 93, 9, 43],
[ 59, 68, 78, 98, 28, 88],
[ 98, 80, 105, 101, 127, 116],
[143, 115, 126, 123, 141, 125]],
[[ 9, 6, 26, 36, 40, 10],
[ 76, 35, 38, 36, 60, 22],
[111, 38, 50, 108, 90, 44],
[116, 50, 74, 119, 110, 60],
[126, 149, 121, 127, 141, 77]]])
nd3
array([[[ 45, 105, 149, 50, 121, 136],
[117, 41, 118, 22, 30, 114],
[131, 107, 40, 43, 141, 99],
[ 57, 44, 101, 113, 19, 71],
[ 53, 148, 122, 50, 66, 142]],
[[ 61, 142, 24, 21, 32, 77],
[ 13, 79, 112, 110, 66, 13],
[ 9, 1, 127, 68, 44, 120],
[144, 133, 17, 82, 68, 120],
[ 81, 59, 127, 11, 69, 74]],
[[ 15, 19, 105, 101, 0, 88],
[ 59, 115, 19, 93, 141, 125],
[143, 68, 4, 98, 9, 0],
[ 98, 80, 78, 86, 28, 116],
[ 32, 25, 126, 123, 127, 43]],
[[126, 50, 74, 127, 141, 44],
[111, 35, 121, 36, 40, 10],
[ 9, 38, 50, 119, 90, 22],
[116, 6, 26, 36, 110, 60],
[ 76, 149, 38, 108, 60, 77]]])
np.sort(nd3,axis = 0)
array([[[ 15, 19, 24, 21, 0, 44],
[ 13, 35, 19, 22, 30, 10],
[ 9, 1, 4, 43, 9, 0],
[ 57, 6, 17, 36, 19, 60],
[ 32, 25, 38, 11, 60, 43]],
[[ 45, 50, 74, 50, 32, 77],
[ 59, 41, 112, 36, 40, 13],
[ 9, 38, 40, 68, 44, 22],
[ 98, 44, 26, 82, 28, 71],
[ 53, 59, 122, 50, 66, 74]],
[[ 61, 105, 105, 101, 121, 88],
[111, 79, 118, 93, 66, 114],
[131, 68, 50, 98, 90, 99],
[116, 80, 78, 86, 68, 116],
[ 76, 148, 126, 108, 69, 77]],
[[126, 142, 149, 127, 141, 136],
[117, 115, 121, 110, 141, 125],
[143, 107, 127, 119, 141, 120],
[144, 133, 101, 113, 110, 120],
[ 81, 149, 127, 123, 127, 142]]])
1. 快速排序
np.sort()与ndarray.sort()都可以,但有区别:
- np.sort()不改变输入
- ndarray.sort()本地处理,不占用空间,但改变输入
2. 部分排序
np.partition(a,k)
有的时候我们不是对全部数据感兴趣,我们可能只对最小或最大的一部分感兴趣。
- 当k为正时,我们想要得到最小的k个数
- 当k为负时,我们想要得到最大的k个数
nd = np.random.randint(0,1000,size = 50)
nd
array([ 86, 235, 944, 674, 359, 296, 169, 697, 279, 557, 737, 97, 216,
463, 538, 96, 473, 275, 939, 306, 210, 758, 299, 500, 650, 437,
943, 968, 666, 773, 513, 41, 450, 268, 899, 372, 87, 990, 809,
503, 124, 544, 820, 898, 786, 437, 389, 874, 454, 694])
np.partition(nd,-5) #前面不排序 最后面五个数是数组中最大的五个数 并没排序
# 负数 倒着,最大的几个数,找到,并没排序
#切片得到
np.partition(nd,-5)[-5:]
array([939, 943, 990, 944, 968])
np.partition(nd,5)[:5]
#切片得到最小的五个数
array([86, 41, 87, 96, 97])