pip install numpy
import numpy as np
data1 = [6, 7.5, 8, 0.1]
arr1 = np.array(data1)
arr1
Out[40]:
array([ 6. , 7.5, 8. , 0.1])
data2 = [[1, 2, 3 ,4],
[5, 6, 7, 8]]
arr2 = np.array(data2)
arr2
Out[41]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
np.zeros(10) # 创建全0对象
Out[51]:
array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.ones((3, 6)) # 创建全1对象
Out[52]:
array([[ 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1.]])
np.empty((2,3,2)) # 创建无具体数值对象
Out[54]:
array([[[ 0.00000000e+000, 6.43320951e-314],
[ 6.72211726e-316, 1.27319747e-313],
[ 1.27319747e-313, 1.27319747e-313]],
[[ 2.96439388e-323, 1.90979621e-313],
[ 0.00000000e+000, 2.75859453e-313],
[ 0.00000000e+000, 7.90505033e-323]]])
np.zeros_like(arr2) # 已一个array对象为模板,创建一个全0的array
Out[55]:
array([[0, 0, 0, 0],
[0, 0, 0, 0]])
np.asarray(arr2) # 将输入转换为一个ndarray,如果输入本身是一个ndarray则不进行转换
Out[57]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
np.arange(10) # 类似于range,但是返回的是ndarray对象
Out[58]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr2.ndim # array对象的规模
Out[44]:
2
arr2.shape # array对象的各维度大小
Out[45]:
(2, 4)
arr2.dtype # array对象内存储的数据类型
Out[49]:
dtype('int32')
np.array(data1, dtype=np.int) # 创建array时指定int类型
Out[63]:
array([6, 7, 8, 0])
np.array(data1, dtype=np.float) # 创建array时指定float类型
Out[64]:
array([ 6. , 7.5, 8. , 0.1])
np.array(['1', '2'], dtype=np.string_) # 创建array时指定string类型
Out[72]:
array([b'1', b'2'],
dtype='|S1')
arr2.astype(np.int) # 转换array的数据类型
Out[73]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
ndarray还有许多其他的数据类型,具体可去查阅资料
大小相等的数组之间的运算都会应用到元素级
data2 = [[1, 2, 3 ,4],
[5, 6, 7, 8]]
arr2 = np.array(data2)
arr2
Out[12]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
arr2 * arr2
Out[17]:
array([[ 1, 4, 9, 16],
[25, 36, 49, 64]])
数组与标量之间的运算
arr2 * 3
Out[18]:
array([[ 3, 6, 9, 12],
[15, 18, 21, 24]])
# 一维数组
In [2]: arr = np.arange(10)
In [3]: arr
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [4]: arr[5]
Out[4]: 5
In [5]: arr[5:8]
Out[5]: array([5, 6, 7])
In [6]: arr[5:8] = 12
In [7]: arr # 将标量赋值给一个切片时,该值会自动传播到整个选区
Out[7]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
In [8]: arr_slice = arr[5:8]
In [9]: arr_slice[0] = 12345
In [10]: arr # 数组切片是原始数组的视图,这意味着数据不会被复制,视图上的任何修改都会反映到源数组上
Out[10]: array([ 0, 1, 2, 3, 4, 12345, 12, 12, 8, 9])
# 如果想要得到一份数组切片的副本而不是视图,需要进行显式的复制操作
arr[5:8].copy()
# 二维数组索引
In [11]: arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
In [12]: arr2d[2]
Out[12]: array([7, 8, 9])
In [13]: arr2d[2][0]
Out[13]: 7
In [14]: arr2d[2, 0]
Out[14]: 7
# 二维数组切片
In [18]: arr2d[:2]
Out[18]:
array([[1, 2, 3],
[4, 5, 6]])
In [19]: arr2d[:2, 1:]
Out[19]:
array([[2, 3],
[5, 6]])
In [20]: arr2d[:, 1:]
Out[20]:
array([[2, 3],
[5, 6],
[8, 9]])
# 布尔型索引
# numpy.random.randn() 返回符合标准正态分布的值,如果需要非标准正态分布比如 N(mu,sigma^2)的值,需要 sigma * numpy.random.randn() + mu
In [28]: name = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
In [29]: data = np.random.randn(7, 4)
In [30]: name
Out[30]:
array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],
dtype='<U4')
In [31]: data
Out[31]:
array([[ 0.59050028, 0.54262242, 0.56663473, 0.6554538 ],
[-0.39923065, -0.82629973, -0.0873751 , 1.21706942],
[-0.11293517, -0.33242528, 1.14774193, 1.03433507],
[ 1.25394817, -0.70304246, -2.65318794, -0.35763238],
[-0.3970596 , 1.72538518, 2.12466681, -0.86388814],
[-0.67229806, -0.73844444, 0.37058963, -1.09828783],
[ 0.60443438, -0.055577 , 0.03728253, 2.28866888]])
In [32]: name == 'Bob' # 比较运算会产生一个布尔型数组
Out[32]: array([ True, False, False, True, False, False, False], dtype=bool)
In [33]: data[name == 'Bob'] # 布尔型数组可以用于索引,布尔型数组的长度必须和被索引的轴的长度一致
Out[33]:
array([[ 0.59050028, 0.54262242, 0.56663473, 0.6554538 ],
[ 1.25394817, -0.70304246, -2.65318794, -0.35763238]])
In [34]: data[name != 'Bob']
Out[34]:
array([[-0.39923065, -0.82629973, -0.0873751 , 1.21706942],
[-0.11293517, -0.33242528, 1.14774193, 1.03433507],
[-0.3970596 , 1.72538518, 2.12466681, -0.86388814],
[-0.67229806, -0.73844444, 0.37058963, -1.09828783],
[ 0.60443438, -0.055577 , 0.03728253, 2.28866888]])
In [36]: data[~(name == 'Bob')]
Out[36]:
array([[-0.39923065, -0.82629973, -0.0873751 , 1.21706942],
[-0.11293517, -0.33242528, 1.14774193, 1.03433507],
[-0.3970596 , 1.72538518, 2.12466681, -0.86388814],
[-0.67229806, -0.73844444, 0.37058963, -1.09828783],
[ 0.60443438, -0.055577 , 0.03728253, 2.28866888]])
In [38]: data[(name == 'Bob') | (name == 'Will')]
Out[38]:
array([[ 0.59050028, 0.54262242, 0.56663473, 0.6554538 ],
[-0.11293517, -0.33242528, 1.14774193, 1.03433507],
[ 1.25394817, -0.70304246, -2.65318794, -0.35763238],
[-0.3970596 , 1.72538518, 2.12466681, -0.86388814]])
In [39]: data[(name == 'Bob') | (name == 'Will')] = 0
In [40]: data
Out[40]:
array([[ 0. , 0. , 0. , 0. ],
[-0.39923065, -0.82629973, -0.0873751 , 1.21706942],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[-0.67229806, -0.73844444, 0.37058963, -1.09828783],
[ 0.60443438, -0.055577 , 0.03728253, 2.28866888]])
# 花式索引:利用整数数组进行索引
# 花式索引和布尔型索引总是创建数据的副本
In [41]: arr = np.empty((8, 4))
In [42]: for i in range(8): arr[i] = i
In [43]: arr
Out[43]:
array([[ 0., 0., 0., 0.],
[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.],
[ 3., 3., 3., 3.],
[ 4., 4., 4., 4.],
[ 5., 5., 5., 5.],
[ 6., 6., 6., 6.],
[ 7., 7., 7., 7.]])
In [44]: arr[[4, 3, 0, 6]] # 以特定顺序选取子集
Out[44]:
array([[ 4., 4., 4., 4.],
[ 3., 3., 3., 3.],
[ 0., 0., 0., 0.],
[ 6., 6., 6., 6.]])
In [45]: arr[[-1, -6]]
Out[45]:
array([[ 7., 7., 7., 7.],
[ 2., 2., 2., 2.]])
In [47]: arr2 = np.arange(32).reshape((8, 4))
In [48]: arr2
Out[48]:
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, 27],
[28, 29, 30, 31]])
In [49]: arr2[[0, 1], [0, 1]] # 一次传入多个索引数组会返回一个一维数组
Out[49]: array([0, 5])
In [52]: arr2[np.ix_([0, 1], [0, 1])] # 选取一个方形区域(会把匹配的数字组成一个对角线)
Out[52]:
array([[0, 1],
[4, 5]])
arr = np.arange.reshape((3, 5))
arr.T # 转置,多维数组转置暂不涉及,没看懂
- 通用函数(ufunc):对ndarray中的元素执行元素级运算
arr = np.arange(10)
np.sqrt(arr) # 开平方
Out[5]:
array([ 0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
from numpy.random import randn
x = randn(8)
y = randn(8)
x
Out[11]:
array([ 0.19943087, -0.43969755, 0.47467068, -0.69043646, -1.584372 ,
-0.56508495, 1.38790099, -1.59400619])
y
Out[12]:
array([ 0.45679909, -0.27603361, -0.20546445, -0.3849307 , 0.46480436,
0.67025896, -1.1392202 , -0.20614324])
np.maximum(x, y) # 元素级最大值
Out[13]:
array([ 0.45679909, -0.27603361, 0.47467068, -0.3849307 , 0.46480436,
0.67025896, 1.38790099, -0.20614324])
其他函数自行查阅资料
- 利用数组进行数据处理:可以代替循环,通常被称作矢量化,要比纯python循环要快一两个数量级
计算一组值的平方根
points = np.arange(1, 4)
points
Out[18]:
array([1, 2, 3])
xs, ys = np.meshgrid(points, points) # np.meshgrid接受两个一维数组,产生两个二维矩阵,对应于两个数组中的所有(x, y)对
xs
Out[24]:
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
ys
Out[25]:
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
np.sqrt(xs ** 2 + ys ** 2)
Out[27]:
array([[ 1.41421356, 2.23606798, 3.16227766],
[ 2.23606798, 2.82842712, 3.60555128],
[ 3.16227766, 3.60555128, 4.24264069]])
将条件逻辑表述为数组运算
numpy.where是三元表达式 x if condition else y的矢量化版本
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, False, True])
np.where(cond, xarr, yarr)
Out[31]:
array([ 1.1, 2.2, 1.3, 2.4, 1.5])
# np.where 的第二个或第三个数值可以使标量值
from numpy.random import randn
arr = randn(4, 4)
arr
Out[32]:
array([[ 1.48935358, 0.16635899, 0.35877451, 0.11799083],
[-0.78907086, -0.3152652 , 0.65792422, 0.08701324],
[ 0.11015433, -1.18763333, -0.67036253, 0.90152057],
[ 0.99085688, -0.8010255 , 0.64804849, -0.59125293]])
np.where(arr > 0, 2, -2)
Out[33]:
array([[ 2, 2, 2, 2],
[-2, -2, 2, 2],
[ 2, -2, -2, 2],
[ 2, -2, 2, -2]])
np.where(arr > 0, 2, arr)
Out[34]:
array([[ 2. , 2. , 2. , 2. ],
[-0.78907086, -0.3152652 , 2. , 2. ],
[ 2. , -1.18763333, -0.67036253, 2. ],
[ 2. , -0.8010255 , 2. , -0.59125293]])
# 数学和统计方法
# 可以通过数组上的一组数学函数对整个数组或者某个轴向上的数据进行统计运算
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
arr.sum()
Out[49]:
45
np.sum(arr)
Out[50]:
45
arr.mean()
Out[51]:
5.0
arr.sum(axis=0) # axis用于计算该轴上的统计值,也可直接写arr.sum(0)
Out[54]:
array([12, 15, 18])
arr.sum(1)
Out[46]:
array([ 6, 15, 24])
arr.cumsum(0) # cumsum 和 cumprod之类的方法不聚合,而是昌盛一个由中间结果组成的数组
Out[53]:
array([[ 1, 2, 3],
[ 5, 7, 9],
[12, 15, 18]], dtype=int32)
方法 说明
sum 对数组中全部或某轴向的元素求和
mean 算数平均数
std, var 标准差和方差,自由度默认为n
min, max 最大值, 最小值
argmin, argmax 最大和最小元素的索引
cumsum 所有元素累积和
cumprod 所有元素累积积
用于布尔型数组的方法
from numpy.random import randn
arr = randn(100)
(arr > 0).sum() # 布尔值会被转换为0和1,所以sum可以用来统计布尔型数组中True的个数
Out[55]:
38
bools = np.array([True, False, True])
bools.any() # any用来测试数组中是否存在一个或多个True
Out[56]:
True
bools.all() # all用来检查数组中是否都是True
Out[57]:
False
# 排序
from numpy.random import randn
arr = randn(8)
arr.sort() # 可以通过sort方法就地排序,而np.sort()返回的是数组的已排序副本
arr
Out[62]:
array([-2.17193055, -1.0539244 , -0.86781328, -0.35368566, -0.01342987,
0.12809625, 0.67388565, 1.51157792])
arr = randn(2, 2)
arr
Out[69]:
array([[-0.04572744, 0.24189971],
[-0.02663575, -0.61676388]])
arr.sort(1) # 按轴排序
arr
Out[70]:
array([[-0.04572744, 0.24189971],
[-0.61676388, -0.02663575]])
names = np.array(['B', 'A', 'B', 'C', 'A'])
np.unique(names)
Out[72]:
array(['A', 'B', 'C'],
dtype='<U1')
方法 说明
unique(x) 计算x中的唯一元素并返回排序结果
intersect1d(x, y) 计算x和y中的公共结果并返回排序结果
union1d(x, y) 计算x和y的并集并返回有序结果
in1d(x, y) 得到一个表示"x的元素是否包含于y"的布尔型数组
setdiff1d(x, y) 集合的差,即元素在x中且不在y中
setxor1d(x, y) 得到存在于一个数组但不同时存在于两个数组中的元素
略
略
numpy.random 下包含的常用随机数生成方法
函数 说明
seed 确定随机数生成器的种子
permutation 返回一个序列的随机排列或返回一个随机排列的范围
shuffle 对一个序列就地随机排列
rand 产生均匀分布的样本值
randit 从给定的上下限范围内随机选取整取
randn 产生正态分布的样本值
normal 产生正态分布的样本值
uniform 产生[0, 1)中均匀分布的样本值