np.random.seed()
和 np.random.RandomState
都用于生成随机数种子,np.random.seed()
是能够直接调用的方法,而 np.random.RandomState
则是一个产生随机数的容器,使用时须要建立实例对象,进而调用实例方法,如 np.random.RandomState(42).uniform()
。html
随机数种子 seed
只有一次有效,在下一次调用产生随机数函数前没有设置 seed
,则仍是产生随机数。若是须要每次都产生随机数,则能够将随机数seed
设置成None
,或者不设置。python
>>> import numpy as np >>> np.random.seed(42) >>> np.random.randint(1, 10, 5) # array([5, 1, 2, 6, 1]) >>> np.random.seed(42) >>> np.random.randint(1, 10, 5) # array([5, 1, 2, 6, 1]) >>> np.random.randint(1, 10, 5) # array([8, 8, 3, 6, 5])
>>> from numpy.random import RandomState >>> r = RandomState(42) >>> r.randint(1, 10, 5) # array([9, 9, 7, 3, 9]) >>> r = RandomState(42) >>> r.randint(1, 10, 5) # array([9, 9, 7, 3, 9]) >>> r = RandomState(None) >>> r.randint(1, 10, 5) # array([8, 3, 2, 6, 5])
>>> import random # 使用Python的Random模块 >>> random.seed(42) >>> random.sample(range(10), 5) # [1, 0, 4, 9, 6] >>> random.sample(range(10), 5) # [6, 9, 1, 4, 5]
numpy.tile(A, n)
用于将一整个数组 A 重复 n 次。 下面是一个简单的例子:数组
>>> a = [1,2,3,4] >>> np.tile(a, 3) # array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4])
然而若是 n 的长度大于 1,则状况就略复杂了。下面看个例子:dom
>>> a = np.array([1,2,3]) >>> np.tile(a, (3, 3)) array([[1, 2, 3, 1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3, 1, 2, 3]])
上面的原始数组 a 为一维,n 的长度为 2,则 tile 函数会将原来的一维拓展为 2 维,再在每一维上重复相应的数组,至关于下面两步:函数
>>> a = np.array([1,2,3]) >>> a = np.expand_dims(a, axis=0) # a 为 array([[1, 2, 3]]) >>> np.tile(a, (3, 3))
上面的状况是 n 的长度大于 a 的维度,另外一种状况是 n 的长度小于 a 的维度:oop
>>> b = np.array([[1,2,3], [4,5,6]]) >>> np.tile(b, 2) array([[1, 2, 3, 1, 2, 3], [4, 5, 6, 4, 5, 6]])
上面的状况是 b 的维度为 2,n 的长度为1,则一样 n 会被扩展为 2,不足的维度用 1 填充,即变成 (1, 2),因此上例中 b 的第一维没有被复制,被复制的是第二维。最后按惯例是一个复杂点的例子:code
>>> c = np.arange(27).reshape((3,3,3)) array([[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]], [[ 9, 10, 11], [12, 13, 14], [15, 16, 17]], [[18, 19, 20], [21, 22, 23], [24, 25, 26]]]) >>> np.tile(c, (2,2,2)) array([[[ 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5], [ 6, 7, 8, 6, 7, 8], [ 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5], [ 6, 7, 8, 6, 7, 8]], [[ 9, 10, 11, 9, 10, 11], [12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17], [ 9, 10, 11, 9, 10, 11], [12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17]], [[18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23], [24, 25, 26, 24, 25, 26], [18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23], [24, 25, 26, 24, 25, 26]], [[ 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5], [ 6, 7, 8, 6, 7, 8], [ 0, 1, 2, 0, 1, 2], [ 3, 4, 5, 3, 4, 5], [ 6, 7, 8, 6, 7, 8]], [[ 9, 10, 11, 9, 10, 11], [12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17], [ 9, 10, 11, 9, 10, 11], [12, 13, 14, 12, 13, 14], [15, 16, 17, 15, 16, 17]], [[18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23], [24, 25, 26, 24, 25, 26], [18, 19, 20, 18, 19, 20], [21, 22, 23, 21, 22, 23], [24, 25, 26, 24, 25, 26]]])
最后出来的结果其实很是具备对称的美感。orm
另外与 numpy.tile()
有密切联系的函数为 numpy.repeat()
,其功能是对应元素重复:htm
>>> np.repeat(13, 5) # array([13, 13, 13, 13, 13])
numpy.repeat()
能够制定要重复的轴 (axis),但若是不指定,则将原数组拉伸为 1 维数组后再对应元素重复:对象
>>> a = np.array([[1,2], [3,4]]) >>> np.repeat(a, 3) # array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]) >>> np.repeat(a, 3, axis=1) array([[1, 1, 1, 2, 2, 2], [3, 3, 3, 4, 4, 4]])
numpy.unique()
的基本用法比较简单,用于返回数组中全部不重复的元素组成的列表 L :
>>> a = np.array([1,2,3,1,2,3,4,5]) >>> L = np.unique(a) array([1, 2, 3, 4, 5])
numpy.unique()
另外附带了三个有用的附加操做,灵活运用可有奇效:
return_index
用于返回原数组中元素的索引 (index)return_inverse
用于返回原数组元素在列表 L 中的索引 (index)return_counts
用于返回原数组中各个不重复元素的出现次数# 计算数组中各个元素的出现次数,并以字典形式返回,和 python 自带的 collections.Counter() 进行效率比较 from collections import Counter >>> a = np.random.randint(0, 10, 10000) >>> %timeit dict(Counter(a)) 1.54 ms ± 46.6 µs per loop >>> %timeit c = dict(zip(*np.unique(a, return_counts=True))) 229 µs ± 1.76 µs per loop >>> c {0: 1003, 1: 1013, 2: 1023, 3: 975, 4: 1019, 5: 956, 6: 979, 7: 996, 8: 1001, 9: 1035}
# 将数组按不重复元素进行切分红多个子数组,返回每一个子数组中元素在原数组中的索引。用于按类别分割数据,scikit-learn 中的 StratifiedShuffleSplit 和 StratifiedKFold 的实现也是基于此。 >>> a = np.random.randint(0, 3, 20) >>> a array([2, 2, 2, 2, 2, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0]) >>> classes, y_indices, class_counts = np.unique(labels, return_inverse=True, return_counts=True) >>> classes, y_indices, class_counts array([0, 1, 2]) array([2, 2, 2, 2, 2, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0]), array([6, 9, 5]) >>> class_indices = np.split(np.argsort(y_indices), np.cumsum(class_counts)[:-1]) >>> class_indices [array([ 9, 16, 14, 10, 6, 19]), array([ 7, 8, 18, 11, 12, 13, 15, 17, 5]), array([4, 3, 2, 1, 0])]
np.argsort()
默认使用的是快速排序,具备不稳定的缺点;若使用归并排序,每一个子数组中元素都会保留原来的顺序:
>>> class_indices = np.split(np.argsort(y_indices, kind="mergesort"), np.cumsum(class_counts)[:-1]) >>> class_indices [array([ 6, 9, 10, 14, 16, 19]), array([ 5, 7, 8, 11, 12, 13, 15, 17, 18]), array([0, 1, 2, 3, 4])]
numpy.average()
和 numpy.mean()
的区别是 numpy.average()
能够计算加权平均:
>>> data = np.arange(6).reshape((3,2)) >>> data array([[0, 1], [2, 3], [4, 5]]) >>> np.average(data, axis=1, weights=[1./4, 3./4]) array([ 0.75, 2.75, 4.75])
numpy.roll(a, shift, axis=None)
用于沿着指定的 axis 滚动数组元素。若不指定 axis,则全部元素依次滚动:
>>> x = np.arange(10).reshape(2,5) >>> x array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) >>> np.roll(x, shift=1) array([[9, 0, 1, 2, 3], [4, 5, 6, 7, 8]]) >>> np.roll(x, shift=1, axis=0) array([[5, 6, 7, 8, 9], [0, 1, 2, 3, 4]]) >>> np.roll(x, shift=1, axis=1) array([[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]])
/