在上面这些方法中,布尔值会被强制转换为1(True)和0(False)。因此,sum经常被用来对布尔型数组中的True值计数:
arr = np.random.randn(100)
print((arr > 0).sum()) #48
另外还有两个方法any和all,它们对布尔型数组非常有用。any用于测试数组中是否存在一个或多个True,而all则检查数组中所有值是否都是True:
bools = np.array([False, False, True, False])
print(bools.any()) #true
print(bools.all()) #false
这两个方法也能用于非布尔型数组,所有非0元素将会被当做True。
1.3.3排序
sort()函数返回输入数组的排序副本。 它有以下参数:
numpy.sort(a,axis,,kind,order)
序号 | 参数及描述 |
---|---|
1 | a 要排序的数组 |
2 | axis 沿着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序 |
3 | kind 默认为'quicksort'(快速排序) |
4 | order 如果数组包含字段,则是要排序的字段 |
import numpy as np
a = np.array([[3,7],[9,1]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 sort() 函数:')
print (np.sort(a))
print ('\n')
print ('沿轴 0 排序:')
print (np.sort(a, axis = 0))
print ('\n')
# 在 sort 函数中排序字段
dt = np.dtype([('name', 'S10'),('age', int)])
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)
print ('我们的数组是:')
print (a)
print ('\n')
print ('按 name 排序:')
print (np.sort(a, order = 'name'))
我们的数组是:
[[3 7]
[9 1]]
调用 sort() 函数:
[[3 7]
[1 9]]
沿轴 0 排序:
[[3 1]
[9 7]]
我们的数组是:
[(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]
按 name 排序:
[(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]
numpy.argsort()函数对输入数组沿给定轴执行间接排序,并使用指定排序类型返回数据的索引数组。 这个索引数组用于构造排序后的数组。
import numpy as np
x = np.array([3, 1, 2])
print ('我们的数组是:')
print (x)
print ('\n')
print ('对 x 调用 argsort() 函数:' )
y = np.argsort(x)
print (y)
print ('\n')
print ('以排序后的顺序重构原数组:')
print (x[y])
print ('\n')
print ('使用循环重构原数组:')
for i in y:
print (x[i])
我们的数组是:
[3 1 2]
对 x 调用 argsort() 函数:
[1 2 0]
以排序后的顺序重构原数组:
[1 2 3]
使用循环重构原数组:
1
2
3
numpy.lexsort()
函数使用键序列执行间接排序。 键可以看作是电子表格中的一列。 该函数返回一个索引数组,使用它可以获得排序数据。 注意,最后一个键恰好是 sort 的主键。
import numpy as np
nm = ('raju','anil','ravi','amar')
dv = ('f.y.', 's.y.', 's.y.', 'f.y.')
ind = np.lexsort((dv,nm))
print ('调用 lexsort() 函数:' )
print (ind)
print ('\n')
print ('使用这个索引来获取排序后的数据:')
print ([nm[i] + ", " + dv[i] for i in ind])
调用 lexsort() 函数:
[3 1 0 2]
使用这个索引来获取排序后的数据:
['amar, f.y.', 'anil, s.y.', 'raju, f.y.', 'ravi, s.y.']
1.3.4唯一化及其它的集合逻辑
NumPy提供了一些针对一维ndarray的基本集合运算。最常用的可能要数np.unique了,它用于找出数组中的唯一值并返回已排序的结果:
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
print(np.unique(names))
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
print(np.unique(ints))
['Bob' 'Joe' 'Will']
[1 2 3 4]
另一个函数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]
1.4用于数组文件的输入输出
NumPy能够读写磁盘上的文本数据或二进制数据。
np.save和np.load是读写磁盘数组数据的两个主要函数。默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为.npy的文件中的:
arr = np.arange(10)
np.save('some_array', arr)
如果文件路径末尾没有扩展名.npy,则该扩展名会被自动加上。然后就可以通过np.load读取磁盘上的数组:
print(np.load('some_array.npy'))
[0 1 2 3 4 5 6 7 8 9]
通过np.savez可以将多个数组保存到一个未压缩文件中,将数组以关键字参数的形式传入即可。
np.savez('array_archive.npz', a=arr, b=arr)
arch = np.load('array_archive.npz')
print(arch['b'])
[0 1 2 3 4 5 6 7 8 9]
如果要将数据压缩,可以使用numpy.savez_compressed:
np.savez_compressed('arrays_compressed.npz', a=arr, b=arr)
1.5线性代数
线性代数(如矩阵乘法、矩阵分解、行列式以及其他方阵数学等)是任何数组库的重要组成部分。不像某些语言(如MATLAB),通过*对两个二维数组相乘得到的是一个元素级的积,而不是一个矩阵点积。因此,NumPy提供了一个用于矩阵乘法的dot函数(既是一个数组方法也是numpy命名空间中的一个函数):
import numpy as np
x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
print(x)
print(y)
print(x.dot(y))
[[ 1. 2. 3.]
[ 4. 5. 6.]]
[[ 6. 23.]
[ -1. 7.]
[ 8. 9.]]
[[ 28. 64.]
[ 67. 181.]]
x.dot(y)等价于np.dot(x, y)。
一个二维数组跟一个大小合适的一维数组的矩阵点积运算之后将会得到一个一维数组:
print(np.ones(3))
print(np.dot(x, np.ones(3)))
[ 1. 1. 1.]
[ 6. 15.]
@符(类似Python 3.5)也可以用作中缀运算符,进行矩阵乘法:
print (x @ np.ones(3))
[ 6. 15.]
from numpy.linalg import inv, qr
X = np.array([[1,2],[3,4]])
q,r=qr(X)
print(X)
print(inv(X))
print(X.dot(inv(X)))
print(r)
[[1 2] [3 4]] [[-2. 1. ] [ 1.5 -0.5]] [[ 1.00000000e+00 0.00000000e+00] [ 8.88178420e-16 1.00000000e+00]] [[-3.16227766 -4.42718872] [ 0. -0.63245553]]
1.6伪随机数生成
numpy.random模块对Python内置的random进行了补充,增加了一些用于高效生成多种概率分布的样本值的函数。例如,你可以用normal来得到一个标准正态分布的4×4样本数组:
samples = np.random.normal(size=(4, 4)) print(samples)
[[-0.2614107 -0.47128902 -1.3459297 -0.87499159] [-0.29068872 0.46052873 -0.97191584 0.04145636] [ 0.04064102 1.45588348 0.80523654 2.33652648] [-0.04158329 -0.46042482 -1.24513472 -0.47444708]]
我们说这些都是伪随机数,是因为它们都是通过算法基于随机数生成器种子,在确定性的条件下生成的。你可以用NumPy的np.random.seed更改随机数生成种子:
np.random.seed(1234)
numpy.random的数据生成函数使用了全局的随机种子。要避免全局状态,你可以使用numpy.random.RandomState,创建一个与其它隔离的随机数生成器:
rng = np.random.RandomState(1234) print(rng.randn(10))
[ 0.47143516 -1.19097569 1.43270697 -0.3126519 -0.72058873 0.88716294 0.85958841 -0.6365235 0.01569637 -2.24268495]