NumPy,是Numerical Python的简称,它是目前Python数值计算中最为重要的基础包。大多数计算包都提供了基于NumPy的科学函数功能,将NumPy的数组对象作为数据交换的通用语。
以下内容将会出现在NumPy中:
基本内容 |
---|
ndarray,一种高效多维数组,提供了基于数组的便捷算术操作以及灵活的广播功能 |
对所有数据进行快速的矩阵计算,而无须编写循环程序 |
对硬盘中数组数据进行读写的工具,并对内存映射文件进行操作 |
线性代数、随机数生成以及傅里叶变换功能 |
用于连接NumPy到C、C++和FORTRAN语言类库的C语言API |
NumPy在内部将数据存储在连续的内存块上,这与其他的Python内建数据结构是不同的。NumPy的算法库是用C语言写的,所以在操作数据内存时,不需要任何类型检查或者其他管理操作。NumPy数组使用的内存量也小于其他Python内建序列。
NumPy的核心特征之一就是N-维数组对象——ndarray。
一个ndarray是一个通用的多维同类数据容器,也就是说,它包含的每一个元素均为相同类型。每一个数组都有一个shape属性,用来表征数组每一维度的数量;每一个数组都有一个dtype属性,用来描述数组的数据类型:
In [4]: data.shape
Out[4]: (2, 3)
In [5]: data.dtype
Out[5]: dtype('float64')
生成数组最简单的方式就是使用array()函数。array函数接收任意的序列型对象(当然也包括其他的数组),生成一个新的包含传递数据的NumPy数组。
例如列表的转换:
In [7]: data1 = [6, 7.5, 8, 0, 1]
In [8]: arr1 = np.array(data1)
In [9]: arr1
Out[9]: array([6. , 7.5, 8. , 0. , 1. ])
嵌套序列的转换,例如同等长度的列表,将会自动转换成多维数组
除非显式地指定,否则np.array会自动推断生成数组的数据类型。数据类型被存储在一个特殊的元数据dtype中。
除了np.array,还有很多其他函数可以创建新数组。例如,给定长度及形状后,zeros可以一次性创造全0数组,ones可以一次性创造全1数组。empty则可以创建一个没有初始化数值的数组。想要创建高维数组,则需要为shape传递一个元组:
In [10]: np.zeros(10)
Out[10]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
In [11]: np.zeros((3,6))
Out[11]:
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
注意:想要使用np.empty来生成一个全0数组,并不安全,有些时候它可能会返回未初始化的垃圾数值。
arange是Python内建函数range的数组版:
In [15]: np.arange(15)
Out[15]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
注意:由于NumPy专注于数值计算,如果没有特别指明的话,默认的数据类型是float64(浮点型)。
函数名 | 描述 |
---|---|
array() | 将输入序列转化为ndarray |
asarray() | 将输入转化为ndarray,但输入已经是ndarray则不再复制 |
arange() | range的数组版本,返回一个数组 |
zeros() | 全0数组 |
ones() | 全1数组 |
数据类型,即dytpe,是一个特殊的对象,它包含了ndarray需要为某一种类型数据所申明的内存块信息(也称为元数据,即表示数据的数据)
可以使用astype方法显式地转换数组的数据类型:
In [2]: arr = np.array([1,2,3,4,5])
In [3]: arr.dtype
Out[3]: dtype('int32')
In [4]: float_arr = arr.astype(np.float64)
In [5]: float_arr.dtype
Out[5]: dtype('float64')
注意:如果把浮点数转换成整数,则小数点后的部分将被消除。
如果你有一个数组,里面的元素都是表达数字含义的字符串,也可以通过astype将字符串转换为数字。
数组之所以重要是因为它允许你进行批量操作而无须任何for循环。NumPy用户称这种特性为向量化。任何在两个等尺寸数组之间的算术操作都应用了逐元素操作的方式:
等尺寸数组之间的操作 | 效果 |
---|---|
arr + arr | 对应位置相加 |
arr - arr | 对应位置相减 |
arr * arr | 对应位置相乘 |
arr / arr | 对应位置相除(注意分母为0的情况) |
标量和数组运算:
数组和标量之间的运算 | 效果 |
---|---|
arr / 2 | arr每个元素的除2 |
arr ** 2 | arr每个元素都做平方运算 |
arr + 2 | arr每个元素都加2 |
同尺寸数组之间的比较,会产生一个布尔值数组:
In [2]: arr = np.array([1,2,3,4,5])
In [6]: arr2 = np.array([3,3,3,3,3])
In [7]: arr > arr2
Out[7]: array([False, False, False, True, True])
不同尺寸的数组间的操作,将会用到广播特性。
一维数组:索引是从0开始,[a:b]实际上是[a,b),[:]将引用数组的所有值
In [8]: arr = np.arange(10)
In [9]: arr
Out[9]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [10]: arr[5]
Out[10]: 5
In [11]: arr[5:8]
Out[11]: array([5, 6, 7])
In [12]: arr[5:8] = 12
In [14]: arr
Out[14]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
注意:区别于Python的内建列表,数组的切片是原数组的视图。这意味着数据并不是被复制了,任何对于视图的修改都会反映到原数组上。
In [15]: arr_slice = arr[5:8]
In [16]: arr_slice
Out[16]: array([12, 12, 12])
In [17]: arr_slice[0]=1111
In [18]: arr
Out[18]: array([ 0, 1, 2, 3, 4, 1111, 12, 12, 8, 9])
如果想要一份数组切片的拷贝而不是一份视图的话,就必须显式地复制这个数组,使用**copy()**函数,如arr[5:8].copy()。
二维数组:
In [19]: arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
In [20]: arr2d
Out[20]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [21]: arr2d[0]
Out[21]: array([1, 2, 3])
In [22]: arr2d[0][0]
Out[22]: 1
在多维数组中,你可以省略后续索引值,返回的对象将是降低一个维度的数组。
注意以上的数组子集选择中,返回的数组都是视图。
二维数组的切片:
In [23]: names = np.array(['bob', 'joe', 'bob', 'will'])
In [24]: data = np.random.randn(4, 3)
In [25]: names
Out[25]: array(['bob', 'joe', 'bob', 'will'], dtype=')
In [26]: data
Out[26]:
array([[ 0.57837371, -1.50775659, -0.34335076],
[-0.01484399, -1.32717111, 1.61517935],
[-1.09299192, -0.00222237, 1.08360099],
[-0.73087258, 0.54748 , -0.65737052]])
假设每个人名都和data数组中的一行相对应,并且我们想要选中所有’Bob’对应的行。与数学操作类似,数组的比较操作(比如==)也是可以向量化的。因此,比较names数组和字符串’Bob’会产生一个布尔值数组:
In [28]: names == 'bob'
Out[28]: array([ True, False, True, False])
在索引数组时可以传入布尔值数组:
In [29]: data[names == 'bob']
Out[29]:
array([[ 0.57837371, -1.50775659, -0.34335076],
[-1.09299192, -0.00222237, 1.08360099]])
布尔值数组的长度必须和数组轴索引长度一致。甚至还可以用切片或整数值或整数值的序列对布尔值数组进行混合和匹配。
**注意:**当布尔值数组的长度不正确时,布尔值选择数据的方法并不会报错,因此我建议在使用该特性的时候要小心。
使用布尔值索引选择数据时,总是生成数据的拷贝,即使返回的数组并没有任何变化。
注意: Python的关键字and和or对布尔值数组并没有用,请使用&(and)和|(or)来代替。
In [30]: mask = (names == 'bob')or(names == 'will')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-30-4f35534bd8f4> in <module>
----> 1 mask = (names == 'bob')or(names == 'will')
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [31]: mask = (names == 'bob')|(names == 'will')
In [32]: mask
Out[32]: array([ True, False, True, True])
神奇索引是NumPy中的术语,用于描述使用整数数组进行数据索引。
In [33]: arr = np.zeros((4,4))
In [34]: for i in range(4):
...: arr[i] = i
...:
In [35]: arr
Out[35]:
array([[0., 0., 0., 0.],
[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.]])
为了选出一个符合特定顺序的子集,你可以简单地通过传递一个包含指明所需顺序的列表或数组来完成:
In [36]: arr[[0, 2]]
Out[36]:
array([[0., 0., 0., 0.],
[2., 2., 2., 2.]])
如果使用负的索引,将从尾部进行选择:负索引从-1开始,-1,-2,-3…
In [37]: arr[[-1, -2]]
Out[37]:
array([[3., 3., 3., 3.],
[2., 2., 2., 2.]])
传递多个索引数组时情况有些许不同,这样会根据每个索引元组对应的元素选出一个一维数组:元素(0,0),(1,1)被选中
In [39]: arr[[0,1],[0,1]]
Out[39]: array([0., 1.])
**注意:**神奇索引与切片不同,它总是将数据复制到一个新的数组中。
转置是一种特殊的数据重组形式,可以返回底层数据的视图而不需要复制任何内容。
数组拥有transpose方法,也有特殊的T属性:
In [40]: arr = np.arange(15).reshape((3,5))
In [41]: arr
Out[41]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
In [42]: arr.T
Out[42]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
转置的应用,比如矩阵的内积,使用np,dot()函数:
In [44]: np.dot(arr.T, arr)
Out[44]:
array([[125, 140, 155, 170, 185],
[140, 158, 176, 194, 212],
[155, 176, 197, 218, 239],
[170, 194, 218, 242, 266],
[185, 212, 239, 266, 293]])
对于更高维度的数组,transpose方法可以接收包含轴编号的元组,用于置换轴(拓展下思维):
ndarray有一个swapaxes方法,该方法接收一对轴编号作为参数,并对轴进行调整用于重组数据:
通用函数,也可以称为ufunc,是一种在ndarray数据中进行逐元素操作的函数。某些简单函数接收一个或多个标量数值,并产生一个或多个标量结果,而通用函数就是对这些简单函数的向量化封装。
有很多ufunc是简单的逐元素转换,称为一元通用函数,sqrt或exp函数
In [2]: arr = np.arange(10)
In [3]: arr
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [4]: np.sqrt(arr)
Out[4]:
array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
还有一些通用函数,比如add或maximum则会接收两个数组并返回一个数组作为结果,因此称为二元通用函数:
In [3]: arr
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [12]: arr2
Out[12]: array([5., 5., 5., 5., 5., 5., 5., 5., 5., 5.])
In [13]: np.maximum(arr, arr2)
Out[13]: array([5., 5., 5., 5., 5., 5., 6., 7., 8., 9.])
这里,numpy.maximum逐个元素地将x和y中元素的最大值计算出来。
一元通用函数:
函数名 | 描述 |
---|---|
abs | 逐元素地计算整数、浮点数或复数地绝对值 |
sqrt | 计算每个元素地的方根(与arr ** 0.5相等) |
square | 计算每个元素的平方(与arr ** 2相等) |
二元通用函数:
函数名 | 描述 |
---|---|
add | 将数组的对应元素相加 |
subtract | 在第二个数组中,将第一个数组中包含的元素去掉 |
multiply | 将数组对应元素相乘 |
divide, floor_divide | 除,整除 |
maximum, fmax | 逐个元素计算最大值,fmax忽略NaN |
minimum, fmin | 逐个元素计算最小值,fmin忽略NaN |
mod | 按元素的求模计算 |
copysign | 将第一个数组的符号值改为第二个数组的符号值 |
greater, greater_equal, less, less_equal, equal, not_equal | 进行逐个元素的比较,返回布尔值数组(>, >=, <, <=, ==, !=) |
logical_and, logical_or, logical_xor | 逐个元素进行罗技操作(&, |, ^) |
使用NumPy数组可以使你利用简单的数组表达式完成多种数据操作任务,而无须写些大量循环。这种利用数组表达式来替代显式循环的方法,称为向量化。
np.meshgrid函数接收两个一维数组,并根据两个数组的所有(x, y)对生成一个二维矩阵
In [18]: points
Out[18]: array([-2, -1, 0, 1])
In [19]: xs, ys = np.meshgrid(points, points)
In [20]: xs
Out[20]:
array([[-2, -1, 0, 1],
[-2, -1, 0, 1],
[-2, -1, 0, 1],
[-2, -1, 0, 1]])
In [23]: ys
Out[23]:
array([[-2, -2, -2, -2],
[-1, -1, -1, -1],
[ 0, 0, 0, 0],
[ 1, 1, 1, 1]])
numpy.where函数是三元表达式x if condition else y的向量化版本。
In [24]: xarr = np.ones(4)
In [25]: yarr = np.zeros(4)
In [26]: condition = np.array([True, False, True, False])
In [27]: np.where(condition, xarr, yarr)
Out[27]: array([1., 0., 1., 0.])
np.where的第二个和第三个参数并不需要是数组,它们可以是标量。假设你有一个随机生成的矩阵数据,并且你想将其中的正值都替换为2,将所有的负值替换为-2,使用np.where会很容易实现:
In [28]: arr = np.random.randn(4)
In [29]: arr
Out[29]: array([-1.11866415, -0.94477767, 0.16956047, 0.21746384])
In [30]: np.where(arr>0, 2, -2)
Out[30]: array([-2, -2, 2, 2])
**注意:**np.where产生的数组是数据的复制,不是视图,不影响原本的数组
可以使用np.where将标量和数组联合,可以像下面的代码那样将arr中的所有正值替换为常数2:
In [31]: arr
Out[31]: array([-1.11866415, -0.94477767, 0.16956047, 0.21746384])
In [32]: np.where(arr > 0, 2, arr)
Out[32]: array([-1.11866415, -0.94477767, 2. , 2. ])
许多关于计算整个数组统计值或关于轴向数据的数学函数,可以作为数组类型的方法被调用。你可以使用聚合函数(通常也叫缩减函数),比如sum、mean和std(标准差),既可以直接调用数组实例的方法,也可以使用顶层的NumPy函数。
In [33]: arr = np.arange(4).reshape((2,2))
In [34]: arr
Out[34]:
array([[0, 1],
[2, 3]])
In [35]: arr.mean()
Out[35]: 1.5
In [36]: np.mean(arr)
Out[36]: 1.5
像mean、sum等函数可以接收一个可选参数axis,这个参数可以用于计算给定轴向上的统计值,形成一个下降一维度的数组:
In [37]: arr.sum(axis = 0)
Out[37]: array([2, 4])
In [38]: arr.sum(axis = 1)
Out[38]: array([1, 5])
arr.sum(0)表示计算行轴向的累和,arr.sum(1)则计算列轴向地累和。
其他方法:cumsum和cumprod并不会聚合,它们会产生一个中间结果:
In [40]: arr = np.array([1, 2, 3, 4, 5])
In [41]: arr.cumsum()
Out[41]: array([ 1, 3, 6, 10, 15], dtype=int32)
在多维数组中,像cumsum这样的累积函数返回相同长度的数组,但是可以在指定轴向上根据较低维度的切片进行部分聚合:
In [44]: arr
Out[44]:
array([[0, 1],
[2, 3]])
In [45]: arr.cumsum(axis=0)
Out[45]:
array([[0, 1],
[2, 4]], dtype=int32)
In [47]: arr.cumprod(axis=1)
Out[47]:
array([[0, 0],
[2, 6]], dtype=int32)
基础数组统计方法:
方法 | 描述 |
---|---|
sum | 沿着轴向计算所有元素地累和 |
mean | 沿着轴向计算数学平均,0长度地数组平均值为NaN |
std, var | 标准差和方差,可调整自由度(默认自由度为n) |
min, max | 最小值和最大值 |
argmin, argmax | 最小值的位置和最大值的位置 |
cumsum | 沿轴向从0开始累加 |
cumprod | 沿轴向从1开始累乘 |
在前面介绍的方法,布尔值会被强制为1(True)和0(False)。因此,sum通常可以用于计算布尔值数组中的True的个数:
In [48]: arr = np.random.randn(10)
In [49]: (arr>0).sum() # 正值的个数
Out[49]: 5
对于布尔值数组,有两个非常有用的方法any和all。any检查数组中是否至少有一个True,而all检查是否每个值都是True:
In [50]: bools = np.array([True, True, False, False])
In [51]: bools.any()
Out[51]: True
In [52]: bools.all()
Out[52]: False
这些方法也可适用于非布尔值数组,所有的非0元素都会按True处理。
和Python的内建列表类型相似,NumPy数组可以使用sort方法按位置排序:
In [53]: arr = np.random.randn(5)
In [54]: arr
Out[54]: array([ 0.49274451, 0.41884218, 0.27810818, -0.36663946, 0.31446952])
In [55]: arr.sort()
In [56]: arr
Out[56]: array([-0.36663946, 0.27810818, 0.31446952, 0.41884218, 0.49274451])
**注意:**sort默认从小到大排序,arr.sort是对原数组进行排序
在多维数组中根据传递的axis值,沿着轴向对每个一维数据段进行排序
顶层的np.sort方法返回的是已经排序好的数组拷贝,而不是对原数组按位置排序。
NumPy包含一些针对一维ndarray的基础集合操作。常用的一个方法是np.unique,返回的是数组中唯一值排序后形成的数组:
In [63]: ints = np.array([1, 1, 2, 3, 3])
In [64]: np.unique(ints)
Out[64]: array([1, 2, 3])
将np.unique和纯Python实现相比较:
In [5]: sorted(set(ints))
Out[5]: [1, 2, 3]
另一个函数,np.in1d,可以检查一个数组中的值是否在另外一个数组中,并返回一个布尔值数组:
In [6]: values = np.arange(5)
In [7]: np.in1d(values, [2, 5])
Out[7]: array([False, False, True, False, False])
In [8]: np.in1d(values, [2, 4])
Out[8]: array([False, False, True, False, True])
数据的集合操作:
方法 | 描述 |
---|---|
unique(x) | 计算x的唯一值,并排序 |
intersect1d(x, y), 这里的"1"是数字1 | 计算x和y的交基,并排序 |
union1d(x, y) | 计算x和y的并集,并排序 |
in1d(x, y) | 计算x中的元素是否包含在y中,返回一个布尔值数组 |
setdiff1d(x, y) | 计算差集,在x但不在y中的x的元素 |
setxor1d(x, y) | 异或集,在x或y中,但不属于x、y交集的元素 |
NumPy可以在硬盘中将数据以文本或二进制文件的形式进行存入硬盘或由硬盘载入。
np.save和np.load是高效存取硬盘数据的两大工具函数。数组在默认情况下是以未压缩的格式进行存储的,后缀名是.npy:
In [11]: arr = np.arange(10)
In [12]: np.save('some_array',arr)
如果文件存放路径中没写.npy时,后缀名会被自动加上。硬盘上的数组可以使用np.load进行载入:
In [13]: np.load('some_array.npy')
Out[13]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
你可以使用np.savez并将数组作为参数传递给该函数,用于在未压缩文件中保存多个数组:
In [14]: np.savez('array_archive.npz', a=arr, b=arr)
当载入一个.npy文件的时候,你会获得一个字典型的对象,并通过该对象很方便地载入单个数组:
In [15]: arch = np.load('array_archive.npz')
In [16]: arch['a']
Out[16]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
如果你的数据已经压缩好了,你可能会想要使用numpy.savez_compressed将数据存入已经压缩的文件:
In [17]: np.savez_compressed('array_archive.npz', a=arr, b=arr)
In [18]: arch = np.load('array_archive.npz')
In [19]: arch['a']
Out[19]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
线性代数,比如矩阵乘法、分解、行列式等方阵数学,是所有数组类库的重要组成部分。和Matlab等其他语言相比,NumPy的线性代数中所不同的是*是矩阵的逐元素乘积,而不是矩阵的点乘积。因此NumPy的数组方法和numpy命名空间中都有一个函数dot,用于矩阵的操作:
二维数组和二维数组矩阵乘积:
In [6]: x
Out[6]:
array([[1, 2, 3],
[4, 5, 6]])
In [7]: y
Out[7]:
array([[1, 1],
[1, 1],
[1, 1]])
In [8]: x.dot(y)
Out[8]:
array([[ 6, 6],
[15, 15]])
In [9]: np.dot(x,y)
Out[9]:
array([[ 6, 6],
[15, 15]])
x.dot(y)等价于np.dot(x, y)
**注意:**要求x和y满足矩阵乘法
二维数组和一维数组之间的矩阵乘积:
In [3]: x
Out[3]:
array([[1, 2, 3],
[4, 5, 6]])
In [4]: np.dot(x,np.ones(3))
Out[4]: array([ 6., 15.])
结果是一个一维数组
特殊符号@也作为中缀操作符,用于点乘矩阵操作:
In [5]: x @ np.ones(3)
Out[5]: array([ 6., 15.])
numpy.linalg拥有一个矩阵分解的标准函数集,以及其他常用函数,例如求逆和行列式求解。
这些函数都是通过在MATLAB和R等其他语言使用的相同的行业标准线性代数库来实现的,例如BLAS、LAPACK或英特尔专有的MKL(数学核心库)(是否使用MKL取决于使用NumPy的版本):
In [11]: X = np.random.randn(3,3)
In [12]: mat = X.T.dot(X)
In [13]: inv(mat)
Out[13]:
array([[ 1.10566219, 2.12576673, -1.16115753],
[ 2.12576673, 5.00401124, -2.62748628],
[-1.16115753, -2.62748628, 1.68342294]])
In [14]: mat.dot(inv(mat))
Out[14]:
array([[ 1.00000000e+00, 2.22044605e-15, 2.22044605e-16],
[ 6.66133815e-16, 1.00000000e+00, -8.88178420e-16],
[ 1.77635684e-15, 0.00000000e+00, 1.00000000e+00]])
In [15]: q, r = qr(mat)
In [16]: r
Out[16]:
array([[-5.45447172, 2.01342902, -0.70198378],
[ 0. , -2.0491966 , -3.70424757],
[ 0. , 0. , 0.30034115]])
常用的numpy.linalg函数:
函数 | 描述 |
---|---|
diag | 将一个方阵的对角(或非对角)元素作为一维数组返回,或者将一维数组转化成一个方阵,并且在非对角线上有零点 |
dot | 矩阵点乘 |
trace | 计算对角元素和 |
det | 计算矩阵的行列式 |
eig | 计算方阵的特征值和特征向量 |
inv | 计算方阵的逆矩阵 |
pinv | 计算矩阵的Moore-Penrose伪逆 |
qr | 计算QR分解 |
svd | 计算奇异值分解 |
solve | 求解x的线性系统Ax=b,其中A是方阵 |
listsq | 计算AX=B的最小二乘解 |
numpy.random模块填补了Python内建的random模块的不足,可以高效地生成多种概率分布下的完整样本值数组。
我们可以称这些为伪随机数,因为它们是由具有确定性行为的算法根据随机数生成器中的随机数种子生成的。你可以通过np.random.seed更改NumPy的随机数种子:
numpy.random中的部分函数列表
函数 | 描述 |
---|---|
seed | 向随机数生成器传递随即状态种子 |
rand | 从均匀分布中抽取样本 |
randn | 从均值0方差1的正态分布中抽取样本(MATLAB型接口) |
randint | 根据给定的由低到高的范围抽取随机整数 |
shuffle | 随机排列一个序列 |
permutation | 返回一个序列的随机排列,或者返回一个乱序的整数范围序列 |
normal | 从正态分布中抽取样本 |
binomial | 从二项分布中抽取样本 |
beta | 从beta分布中抽取样本 |
chisquare | 从卡方分布中抽取样本 |
其中的内容会不定期补充。
上述内容均是来自书籍《利用Python进行数据分析》