1.3 利用数组进行数据处理
1.3.1 将条件逻辑表述为数组运算
Numpy.where函数是三元表达式 x if condition else y的矢量化版本
示例1:有一个布尔数组和两个值数组
import numpy as np
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = [(x if c else y)
for x, y, c in zip(xarr, yarr, cond)]
print(list(zip(xarr, yarr, cond)))
print(result)
[(1.1, 2.1, True), (1.2, 2.2, False), (1.3, 2.3, True), (1.4, 2.4, True), (1.5, 2.5, False)]
[1.1, 2.2, 1.3, 1.4, 2.5]
如上代码,问题如下:
- 它对大数组的处理不是很快(所有的工作都是纯Python完成的)
- 无法用于多维数组
示例2:使用np.where
import numpy as np
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = np.where(cond, xarr, yarr)
print(result)
[1.1 2.2 1.3 1.4 2.5]
PS:np.where的第二个参数和第三个参数不必是数组,它们都可以是标量值。
Where通常用于根据另一个数组而产生一个新的数组
示例3:有一个由随机数据组成的矩阵,所有正值替换为2,所有负值替换为-2
arr = np.random.randn(4, 4)
print(arr)
arr = np.where(arr > 0, 2, -2)
print(arr)
[[-0.56833799 0.55842545 -0.26764554 -0.93447192]
[ 0.56168595 -0.32974735 1.5823422 -0.09394168]
[ 2.00346164 1.68308417 0.4891715 -1.28706899]
[ 1.09719467 1.10823727 0.63749302 -0.20085611]]
[[-2 2 -2 -2]
[ 2 -2 2 -2]
[ 2 2 2 -2]
[ 2 2 2 -2]]
示例4:只将正值设置为2
arr = np.where(arr > 0, 2, arr)
print(arr)
[[ 2. -0.00773559 2. 2. ]
[ 2. -1.87703301 -0.87108499 -1.12912804]
[ 2. -0.85075233 -1.76446195 2. ]
[ 2. -0.36148058 2. 2. ]]
示例5:有两个布尔型数组cond1和cond2,根据4种不同的布尔值组合实现不同的赋值操作
np.where(cond1 & cond2,0,
np.where(cond1,1,
np.where(cond2,2,3)))
result = 1 * (cond1 - cond2) + 2 * (cond2 & -cond1) +3 * -(cond1|cond2)
1.3.2 数学和统计方法
可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算;sum,mean以及标准差std等聚合计算,既可以当做数组的实例方法调用,也可以当作顶级NumPy函数使用
示例1:
arr = np.random.randn(5, 4) # 正态分布数据
print(arr.mean())
print(arr.sum())
-0.3162731268320424
-6.325462536640848
示例2:mean和sum这类的函数可以接受一个axis参数(用于计算该轴向上的统计值)
arr = np.random.randn(5, 4) # 正态分布数据
print(arr.mean(axis=1))
print(arr.sum(0))
[ 0.28352816 -0.38059715 0.67146828 -0.28121362 -0.2369854 ]
[ 0.49158264 0.31362069 1.04459776 -1.62500007]
示例3:cumsum和cumprod之类的方法则不聚合,而是产生一个由中间结果组成的数组
arr = np.array([[0,1,2],[3,4,5],[6,7,8]])
print(arr)
print(arr.cumsum(0))
print(arr.cumprod(1))
[[0 1 2]
[3 4 5]
[6 7 8]]
[[ 0 1 2]
[ 3 5 7]
[ 9 12 15]]
[[ 0 0 0]
[ 3 12 60]
[ 6 42 336]]
基本数组统计方法:
1.3.3 用于布尔型数组的方法
在上面这些方法中,布尔值会被强制转换为1(True)和0(False),
示例1:sum经常被用来对布尔型数组中的True值计数:
arr = np.random.randn(100)
print((arr > 0).sum()) # 正值的数量
45
另外还有两方法:
- Any 用于测试数组中是否存在一个或多个True
- All 用于检查数组中的值是否都是True
示例2:any和all
bools = np.array([False,False,True,True])
print(bools.any())
print(bools.all())
True
False
1.3.4 排序
示例1:跟Python内置的列表类型一样,NumPy数组也可用通过sort方法就地排序
arr = np.random.randn(5)
print(arr)
arr.sort()
print(arr)
[ 1.29449706 0.55664119 -1.08227274 0.65893081 -1.0295693 ]
[-1.08227274 -1.0295693 0.55664119 0.65893081 1.29449706]
示例2:多维数组可以在任何一个轴向上进行排序,只需将轴编号传给sort即可
arr = np.random.randn(5,3)
print(arr)
arr.sort(1)
print('---------')
print(arr)
[[-0.62105519 1.02798002 2.14997418]
[-0.02283647 1.79487225 0.36493905]
[-0.60201768 0.4962236 0.57311111]
[ 0.07698052 0.33457888 -0.05231778]
[ 0.0720138 -0.0043807 0.32743015]]
---------
[[-0.62105519 1.02798002 2.14997418]
[-0.02283647 0.36493905 1.79487225]
[-0.60201768 0.4962236 0.57311111]
[-0.05231778 0.07698052 0.33457888]
[-0.0043807 0.0720138 0.32743015]]
arr = np.random.randn(5,3)
print(arr)
arr.sort(0)
print('---------')
print(arr)
[[-0.54362949 1.62302362 -0.76459936]
[-0.91396233 -0.37510621 1.23642129]
[-0.07234912 1.35056886 -0.62331843]
[ 0.11284198 0.36602232 -1.17381419]
[ 0.29541662 0.35208214 -0.19710914]]
---------
[[-0.91396233 -0.37510621 -1.17381419]
[-0.54362949 0.35208214 -0.76459936]
[-0.07234912 0.36602232 -0.62331843]
[ 0.11284198 1.35056886 -0.19710914]
[ 0.29541662 1.62302362 1.23642129]]
顶级方法np.sort返回的是数组的已排序副本,而就地排序则会修改数组本身
示例3:计算数组分位数最简单的办法是对其进行排序,然后选取特定位置的值:
arr = np.random.randn(1000)
arr.sort()
print(arr[int(0.05 * len(arr))]) # 5%分位数
-1.599647429699794
1.3.5 唯一化以及其他的集合逻辑
示例1:np.unique
names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
print(np.unique(names))
print(names)
['Bob' 'Joe' 'Will']
['Bob' 'Joe' 'Will' 'Bob' 'Will' 'Joe' 'Joe']
示例2:np.in1d
values = np.array([6,0,0,3,2,5,6])
print(np.in1d(values,[2,3,6]))
[ True False False True True False True]