numpy数组向量化的操作,可以避免纯Python的代码大量的循环。
>>> x = np.arange(5)
>>> y = np.array([1,2,3,4,5])
>>> x
array([0, 1, 2, 3, 4])
>>> y
array([1, 2, 3, 4, 5])
>>> np.sqrt(x**2+y**2)
array([1. , 2.23606798, 3.60555128, 5. , 6.40312424])
1 将条件逻辑作为数组操作
numpy.where(cond, xarry,yarry)函数是三元表达式x if condition else y 的向量化版本。
>>> cond = np.array([True,False,True,True,False])
>
>>> result = [(x if cond else y) for x,y, cond in zip(x,y,cond)]
>
>>> result
[0, 2, 2, 3, 5]
#用numpy.where: 当数组是多维的时候就体现出它的优势了。
>>> np.where(cond,x,y)
array([0, 2, 2, 3, 5])
第二和第三个参数并不需要是数组,标量也可以。where在数据分析里的一个典型用法就是根据一个数组生成一个新的数组。
>>> arr = np.random.randn(4,4)
>>> arr
array([[-1.94636384, 0.47447052, 0.24799631, 0.64327261],
[-0.68026503, -0.97683216, 0.34171871, 0.43870184],
[-0.80524358, 2.34316712, -0.88535818, -0.421693 ],
[-0.29505739, 1.13508579, 0.19988486, 2.16604002]])
#将所有大于0的数换为2,所有小于0的数换为-2
>>> np.where(arr>0, 2,-2)
array([[-2, 2, 2, 2],
[-2, -2, 2, 2],
[-2, 2, -2, -2],
[-2, 2, 2, 2]])
where 还可以进行嵌套,实现一些非常复杂的逻辑。这点个人认为很强大。
#比如说有条件cond1,cond2, 需要根据cond1和cond2的布尔组合来赋值,如果用if 和 else 就会很长
result = []
>>> for i in range(n):
if cond1[i] and cond2[i]:
result.append(0)
elif cond1[i]:
result.append(1)
elif cond2:
result.append(2)
else:
result.append(3)
#如果用where:
np.where(cond1&cond2, 0,
np.where(cond1,1 ,
np.where(cond2, 2, 3)))
2 数学和统计方法
可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计分析。如:
sum(求和),std(标准差), mean(算术平均) 等聚合计算(aggregation),可以当做数组的实例方法调用,也可以当做numpy 函数使用。
>>> arr = np.random.randn(5,4)
>>> arr
array([[ 1.31203615, 0.49765205, -1.53994717, -1.53514626],
[-1.29331024, -1.21922716, 0.30392973, -1.04224164],
[ 1.27097779, -1.46335013, -0.11107992, 0.44894967],
[ 0.19714806, 0.99414584, 0.00613592, -0.6054693 ],
[-0.72410901, -0.50590817, 2.10223207, 0.43335613]])
>>> arr.mean()
-0.12366127881913236
>>> np.mean(arr)
-0.12366127881913236
#mean,sum这类函数可以接受一个axis参数,用于计算 该轴上的统计值,最终结果是一个少一维的数组
>>> arr.mean(axis = 1)
array([-0.31635131, -0.81271233, 0.03637435, 0.14799013, 0.32639276])
>>> arr.sum(axis = 0)
array([ 0.76274275, -1.69668757, 0.76127064, -2.3005514 ])
其他一些方法如cumsum(所有元素的累积和), cumprod (所有元素的累计积)方法则一个由中间结果组成的数组。
>>> arr = np.arange(9).reshape(3,3)
>>> arr
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> arr.cumsum()
array([ 0, 1, 3, 6, 10, 15, 21, 28, 36], dtype=int32)
>>> arr.cumsum(axis = 0)
array([[ 0, 1, 2],
[ 3, 5, 7],
[ 9, 12, 15]], dtype=int32)
>>> arr.cumsum(axis = 1)
array([[ 0, 1, 3],
[ 3, 7, 12],
[ 6, 13, 21]], dtype=int32)
#还有一些方法,如argmax,argmin 为最大最小元素的索引
>>> arr.argmax()
8
>>> arr.argmax(axis = 0)
array([2, 2, 2], dtype=int64)
3. 用于布尔型数组的方法
在上面的方法中,布尔型数值通常被转换为1和0
所以,可以用sum来统计所you为真的值的计数
另外还有两个方法any, all,非常有用
any 用于测试数组中是否存在一个或多个为true 的值
all 用于检查数组中是否所有都为True
>>> a = np.random.randn(50)
#统计所有大于0的数
>>> (a>0).sum()
24
>>> (a>0).any()
True
>>> (a>0).all()
False
4.排序
和Python列表内置的排序sort一样,numpy也有sort方法就地排序。
>>> arr = np.random.randn(8)
>>> arr
array([-0.32846512, -0.72030816, 0.65995858, 1.82404689, -0.70415569,
1.52879691, 0.06548983, -1.55406387])
>>> arr.sort()
>>> arr
array([-1.55406387, -0.72030816, -0.70415569, -0.32846512, 0.06548983,
0.65995858, 1.52879691, 1.82404689])
#多维数组只需要传入axis参数,就可以沿着某个轴进行排序
>>> arr1 = np.random.randn(5,3)
>>> arr1
array([[ 2.01193113, -0.2257034 , -1.37088669],
[ 0.25704266, -0.23075886, -0.54990301],
[-0.02991026, -0.49935258, -0.25514291],
[ 1.58703722, 0.6311043 , -0.08888583],
[ 0.32241217, -1.59664737, -0.89960456]])
>>> arr1.sort(axis = 1)
>>> arr1
array([[-1.37088669, -0.2257034 , 2.01193113],
[-0.54990301, -0.23075886, 0.25704266],
[-0.49935258, -0.25514291, -0.02991026],
[-0.08888583, 0.6311043 , 1.58703722],
[-1.59664737, -0.89960456, 0.32241217]])
np.sort() 返回的是已排序的副本,而就地排序会修改数组本身。
>>> arr = np.random.randn(10)
>>> arr
array([ 0.22338822, -0.20591257, -0.6998268 , -0.50764967, -1.78213722,
0.51288778, 0.0322092 , 0.79605205, 0.79525635, -0.6707283 ])
>>> np.sort(arr)
array([-1.78213722, -0.6998268 , -0.6707283 , -0.50764967, -0.20591257,
0.0322092 , 0.22338822, 0.51288778, 0.79525635, 0.79605205])
#arr 没有被修改:
>>> arr
array([ 0.22338822, -0.20591257, -0.6998268 , -0.50764967, -1.78213722,
0.51288778, 0.0322092 , 0.79605205, 0.79525635, -0.6707283 ])
其他排序方法后面再说。
5. 唯一化以及其他集合逻辑
针对一维数组,numpy提供了一些基本的集合运算。
比如numpy提供了np.unique(), 用于找出数组中的唯一值并返回排序结果。
如下:
>>> ints = np.array([1,1,1,2,0,0,90,8,88,2])
>>> np.unique(ints)
array([ 0, 1, 2, 8, 88, 90])
#和纯Python代码相比:
>>> sorted(set(ints))
[0, 1, 2, 8, 88, 90]