3. 数值计算(Numpy)¶
3.1. 数组创建¶
数组的创建方式有很多,较便捷的方式有以下三种
直接创建
[1]:
import numpy as np
[2]:
a = np.array([1, 2, 3, 4, 5])
a
[2]:
array([1, 2, 3, 4, 5])
类 range
[3]:
a = np.arange(10)
a
[3]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
[4]:
a = np.arange(1, 10, 2)
a
[4]:
array([1, 3, 5, 7, 9])
创建带尾巴的
[5]:
a = np.linspace(0, 10, 2)
a
[5]:
array([ 0., 10.])
更多便捷创建函数
函数 | 功能 |
---|---|
asarray | 将输入转换为 ndarray,若输入本身是 ndarray 就不复制 |
ones、ones_like | 根据指定形状和 dtype 创建一个全 1 数组 |
zeros、zeros_like | 根据指定形状和 dtype 创建一个全 0 数组 |
empty、empty_like | 创建新数组,但只分配内存空间不赋值 |
eye、identity | 创建一个正方的N×N单位矩阵(对角线为1,其余为0 |
在 pandas 中尽量不要使用 np.empty(),这个函数创建的数组里面是有值的,除非你确定创建的这个数组能被完全赋值,否则后面运算起来很麻烦,这些“空值”的布尔类型是 True,而且 dropna() 方法删不掉。想创建空的 Series ,可以使用 Series(np.nan,index=???) 这样。
3.2. ndarray 对象属性¶
.reshape(shape) 改变数组维度
[6]:
b = np.linspace(0, 7, 8)
b
[6]:
array([ 0., 1., 2., 3., 4., 5., 6., 7.])
[7]:
b = np.linspace(0, 7, 8).reshape(2, 4)
b
[7]:
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.]])
[8]:
b = np.arange(0, 8).reshape(2, 2, 2)
b
[8]:
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
.astype(dtype) 改变数组格式
[9]:
print b.dtype
b
int64
[9]:
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
[10]:
b.astype(float)
[10]:
array([[[ 0., 1.],
[ 2., 3.]],
[[ 4., 5.],
[ 6., 7.]]])
.transpose(*axes) 转置, transpose 的属性一直没搞懂
[11]:
b = np.arange(8).reshape(2, 4)
b
[11]:
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
[12]:
b.T
[12]:
array([[0, 4],
[1, 5],
[2, 6],
[3, 7]])
[13]:
b.transpose()
[13]:
array([[0, 4],
[1, 5],
[2, 6],
[3, 7]])
.sort 排序
[14]:
a = np.array([[1,4],[3,1]])
[15]:
np.sort(a) # sort along the last axis
[15]:
array([[1, 4],
[1, 3]])
[16]:
np.sort(a, axis=None) # sort the flattened array
[16]:
array([1, 1, 3, 4])
[17]:
np.sort(a, axis=0) # sort along the first axis
[17]:
array([[1, 1],
[3, 4]])
stats 基本统计
[18]:
arr = np.arange(12).reshape(3,4)
[19]:
arr
[19]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
[20]:
arr.sum()
[20]:
66
[21]:
np.sum(arr)
[21]:
66
[22]:
arr.mean(0) # 列均值
[22]:
array([ 4., 5., 6., 7.])
[23]:
arr.mean(1) # 行均值
[23]:
array([ 1.5, 5.5, 9.5])
更多统计方法
sum | 求和 |
mean | 均值 |
std,var | 标准差和方差 |
min,max | 最小值和最大值 |
argmin,argmax | 最小值和最大值的索引 |
cumsum | 累积和 |
cumprod | 累积积 |
3.3. 数组间运算¶
[24]:
a = np.arange(8).reshape(2, 4)
b = np.ones_like(a)
[25]:
a + b
[25]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
[26]:
a * 2
[26]:
array([[ 0, 2, 4, 6],
[ 8, 10, 12, 14]])
3.4. 索引和切片¶
基本索引
[27]:
foo = np.arange(10)
foo
[27]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
[28]:
bar = foo[:5].copy() # 若没有 copy,则 bar 的改变会影响 foo
[29]:
bar
[29]:
array([0, 1, 2, 3, 4])
[30]:
bar[:] = 1
[31]:
bar
[31]:
array([1, 1, 1, 1, 1])
[32]:
foo
[32]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
二维和三维数组如何索引?
[33]:
arr2d = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
arr2d
[33]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
[34]:
arr2d[2, 0]
[34]:
7
[35]:
arr3d = np.array([[[1, 2, 3],[4, 5, 6]],
[[7, 8, 9],[10, 11, 12]]])
[36]:
arr3d[0]
[36]:
array([[1, 2, 3],
[4, 5, 6]])
[37]:
arr3d[0, 1, 2]
[37]:
6
切片 从第 0 轴开始的
[38]:
arr2d
[38]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
[39]:
arr2d.shape
[39]:
(3, 3)
[40]:
arr2d[:1]
[40]:
array([[1, 2, 3]])
[41]:
arr2d[1:4] # 理论上第0轴没有4这个基数
[41]:
array([[4, 5, 6],
[7, 8, 9]])
[42]:
arr2d[:2, :1]
[42]:
array([[1],
[4]])
布尔型索引
[43]:
from numpy.random import randn
data = randn(7, 4) # 生成 7*4 个均值为 0,标准差为 1 的数组
data
[43]:
array([[ 0.51659011, -0.14527543, 0.73750985, -0.07181445],
[-0.26857463, 0.34883972, 0.07129706, 0.95455506],
[ 0.43307006, -0.04072156, -1.32443926, 0.1124177 ],
[ 1.39517115, -0.54127346, -0.70176892, -0.21847743],
[ 2.69939163, 0.9403898 , -0.0578206 , 0.50806596],
[-0.41641312, -0.45169815, 0.31717456, -0.34085142],
[ 0.44102963, 0.96447336, -2.92258682, -1.22429012]])
[44]:
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'] )
names == 'Bob'
[44]:
array([ True, False, False, True, False, False, False], dtype=bool)
当两个轴长度一致时,可以用布尔型的数组切片,比如此例切的是 axis 0
[45]:
data[names == 'Bob']
[45]:
array([[ 0.51659011, -0.14527543, 0.73750985, -0.07181445],
[ 1.39517115, -0.54127346, -0.70176892, -0.21847743]])
[46]:
data[names == 'Bob', 2:]
[46]:
array([[ 0.73750985, -0.07181445],
[-0.70176892, -0.21847743]])
[47]:
data[~(names == 'Bob')]
[47]:
array([[-0.26857463, 0.34883972, 0.07129706, 0.95455506],
[ 0.43307006, -0.04072156, -1.32443926, 0.1124177 ],
[ 2.69939163, 0.9403898 , -0.0578206 , 0.50806596],
[-0.41641312, -0.45169815, 0.31717456, -0.34085142],
[ 0.44102963, 0.96447336, -2.92258682, -1.22429012]])
布尔型数组求并集
[48]:
mask = (names == "Bob") | (names == "Will")
mask
[48]:
array([ True, False, True, True, True, False, False], dtype=bool)
[49]:
data[mask]
[49]:
array([[ 0.51659011, -0.14527543, 0.73750985, -0.07181445],
[ 0.43307006, -0.04072156, -1.32443926, 0.1124177 ],
[ 1.39517115, -0.54127346, -0.70176892, -0.21847743],
[ 2.69939163, 0.9403898 , -0.0578206 , 0.50806596]])
3.5. 利用数组做数据处理¶
将条件逻辑表述为数组运算, np.where 是一个极其有用的三元函数,它其实是一个条件运算函数,即 foo if cond else bar
[50]:
xarr = np.arange(1.1, 1.6, 0.1)
[51]:
xarr
[51]:
array([ 1.1, 1.2, 1.3, 1.4, 1.5])
[52]:
yarr = np.arange(2.1, 2.6, 0.1)
[53]:
yarr
[53]:
array([ 2.1, 2.2, 2.3, 2.4, 2.5])
[54]:
cond = np.array([True, False, True, True, False])
根据 cond 的值选取 xarr 和 yarr 的值
[55]:
result = [(x if c else y)
for x, y, c in zip(xarr, yarr, cond)]
[56]:
result
[56]:
[1.1000000000000001,
2.2000000000000002,
1.3000000000000003,
1.4000000000000004,
2.5000000000000004]
不够简洁,可用 where 改写
[57]:
result = np.where(cond, xarr, yarr)
result
[57]:
array([ 1.1, 2.2, 1.3, 1.4, 2.5])
np.where 的第二个和第三个参数不必是数组,他们都是标量值
[58]:
arr = randn(4,4)
arr
[58]:
array([[ 2.0086379 , -0.33799069, 0.48232499, 0.00343801],
[-0.54010599, 1.63779772, 1.22284334, -1.34602676],
[ 0.80309605, -0.82099082, -0.8703366 , 0.20060704],
[ 1.10812415, -0.01419402, -0.30237458, 1.30298964]])
[59]:
np.where(arr > 0, 2, -2) # 正值设置为 2,负值设置为 -2
[59]:
array([[ 2, -2, 2, 2],
[-2, 2, 2, -2],
[ 2, -2, -2, 2],
[ 2, -2, -2, 2]])
└ 这个代码的意思其实就是 >0 则 2,else -2
3.6. 其他通用函数¶
一元函数
函数名 | 功用 |
---|---|
abs,fabs | 整数、浮点、复数的绝对值,对于非复数,可用更快的 fabs |
sqrt | 平方根,等于 arr**0.5 |
square | 平方,等于 arr**2 |
exp | 以 e 为底的指数函数 |
log,log10,log2,log1p | 以 e 为底的对数函数 |
sign | 计算各元素的正负号,1(正),0(零),-1(负) |
ceil | 计算大于等于该值的最小整数 |
floor | 计算小于等于该值的最大整数 |
rint | round int,四舍五入到整数 |
modf | 将数组的整数和小数部分以两个独立数组的形式返回 |
isnan | 返回一个 “哪些值是 NaN” 的布尔型数组 |
isfinite,isinf | 返回是否是有穷(无穷)的布尔型数组 |
cos,cosh,sin,sinh,tan,tanh | 普通和双曲型三角函数 |
arccos,arccosh…等同上 | 反三角函数 |
logical_not | 计算个元素 not x 的真值,等于 -arr |
unique | 计算元素唯一值并返回排序后的结果 |
二元函数
函数名 | 功用 |
---|---|
add | 加法,+ |
subtract | 减法,- |
multiply | 乘法,* |
divide,floor_divide | 除法和地板除,/ 和 // |
power | 乘方,** |
maximum,fmax | 元素级最大值,fmax 将忽略 NaN |
minimum,fmin | 同上 |
mod | 取模,% |
copysign | 将第二数组元素的符号复制给第一数组 |
greater(_equal),less(*equal),(not*) equal | 字面意义,返回布尔数组 |
logical_and,logical_or,logical_xor | 字面意义,返回布尔数组 |