In [1]:
import numpy 
numpy.__version__
Out[1]:
'1.16.2'
In [2]:
import numpy as np
L = list(range(10))
L
Out[2]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]:
type(L[0])
Out[3]:
int
In [4]:
L2 = [str(c) for c in L]
L2
Out[4]:
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

创建数组

从Python列表创建数组

In [6]:
np.array([1,2,3,4])
Out[6]:
array([1, 2, 3, 4])
In [5]:
np.array([1,2,3,4.55])
Out[5]:
array([1.  , 2.  , 3.  , 4.55])
In [8]:
np.array([1,2,3,4], dtype='float32')
Out[8]:
array([1., 2., 3., 4.], dtype=float32)
In [9]:
# 嵌套列表构成多维数组
np.array([range(i, i+3) for i in [2,4,6]])
Out[9]:
array([[2, 3, 4],
       [4, 5, 6],
       [6, 7, 8]])

从头创建数组

In [10]:
np.zeros(10, dtype=int)
Out[10]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
In [11]:
np.ones((3,5), dtype=float)
Out[11]:
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
In [12]:
np.full((3,5), 3.14)
Out[12]:
array([[3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14]])
In [13]:
np.arange(0,20,2)
Out[13]:
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
In [14]:
np.linspace(0,1,5)
Out[14]:
array([0.  , 0.25, 0.5 , 0.75, 1.  ])
In [15]:
np.random.random((3,3))
Out[15]:
array([[0.34533413, 0.60646007, 0.4806022 ],
       [0.08625868, 0.93236771, 0.75759323],
       [0.83404796, 0.68026247, 0.91537343]])
In [16]:
np.random.normal(0,1,(3,3))
Out[16]:
array([[ 0.05375534, -1.03669755, -0.94419724],
       [ 0.84103917, -0.21809516, -1.1767971 ],
       [ 1.06116151, -1.42486188, -0.91931836]])
In [17]:
np.random.randint(0,10,(3,3))
Out[17]:
array([[8, 9, 7],
       [9, 2, 2],
       [0, 1, 0]])
In [18]:
np.eye(3)
Out[18]:
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
In [19]:
# 创建一个由3个整型数组成的微初始化的数组
# 数组的值是内存空间中的任意值
np.empty(3)
Out[19]:
array([1., 1., 1.])

Numpy数组基础

In [20]:
np.random.seed(0)

x1 = np.random.randint(10, size = 6) # 一维数组
x2 = np.random.randint(10, size = (3,4)) # 二维数组
x3 = np.random.randint(10, size = (3,4,5)) # 三维数组
In [23]:
print("x3 ndim: ", x3.ndim) #数组的维度
print("x3 shape:", x3.shape) #数组每个维度的大小
print("x3 size:", x3.size) #数组的总大小
print("dtype: ", x3.dtype) #数组的数据类型
print("itemsize: ", x3.itemsize, "bytes") #每个数组元素字节大小
print("nbytes: ", x3.nbytes, "bytes")
x3 ndim:  3
x3 shape: (3, 4, 5)
x3 size: 60
dtype:  int64
itemsize:  8 bytes
nbytes:  480 bytes

数组索引:获取单个元素

In [24]:
x1
Out[24]:
array([5, 0, 3, 3, 7, 9])
In [25]:
x1[-1]
Out[25]:
9
In [26]:
x1[-2]
Out[26]:
7
In [27]:
x2
Out[27]:
array([[3, 5, 2, 4],
       [7, 6, 8, 8],
       [1, 6, 7, 7]])
In [28]:
x2[0,0]
Out[28]:
3
In [29]:
x2[2, -1]
Out[29]:
7

注意:和Python列表不同,Numpy数组是固定类型的,这意味着当你试图将一个浮点值插入一个整型数组时,浮点值会被截短成整型。并且这种截短是自动完成的,不会给你提示或警告!

In [30]:
x1
Out[30]:
array([5, 0, 3, 3, 7, 9])
In [31]:
x1[0] = 3.14159
x1
Out[31]:
array([3, 0, 3, 3, 7, 9])

数组切片获得子数组

x[start:stop:step]

In [32]:
x = np.arange(10)
x
Out[32]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [33]:
x[:5]
Out[33]:
array([0, 1, 2, 3, 4])
In [34]:
x[5:]
Out[34]:
array([5, 6, 7, 8, 9])
In [35]:
x[4:7]
Out[35]:
array([4, 5, 6])
In [36]:
x[::2]
Out[36]:
array([0, 2, 4, 6, 8])
In [37]:
x[1::2]
Out[37]:
array([1, 3, 5, 7, 9])
In [38]:
# 逆序数组
x[::-1]
Out[38]:
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
In [39]:
x[5::-2]
Out[39]:
array([5, 3, 1])
In [40]:
x2
Out[40]:
array([[3, 5, 2, 4],
       [7, 6, 8, 8],
       [1, 6, 7, 7]])
In [41]:
x2[:2,:3]
Out[41]:
array([[3, 5, 2],
       [7, 6, 8]])
In [42]:
x2[::-1,::-1]
Out[42]:
array([[7, 7, 6, 1],
       [8, 8, 6, 7],
       [4, 2, 5, 3]])

数组变形

In [44]:
grid = np.arange(1,10).reshape((3,3))
print(grid)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
In [47]:
x = np.array([1,2,3])
x.reshape((1,3))
Out[47]:
array([[1, 2, 3]])
In [48]:
# 通过newaxis获得的行向量
x[np.newaxis,:]
Out[48]:
array([[1, 2, 3]])
In [50]:
x.reshape((3,1))
Out[50]:
array([[1],
       [2],
       [3]])
In [52]:
x[:,np.newaxis]
Out[52]:
array([[1],
       [2],
       [3]])

数组拼接和分裂

In [53]:
x = np.array([1,2,3])
y = np.array([3,2,1])

np.concatenate([x, y])
Out[53]:
array([1, 2, 3, 3, 2, 1])
In [54]:
z = [99,99,99]
print(np.concatenate([x, y, z]))
[ 1  2  3  3  2  1 99 99 99]
In [55]:
grid = np.array([[1,2,3],[4,5,6]])
# 沿着第一个轴拼接
np.concatenate([grid, grid])
Out[55]:
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
In [56]:
# 沿着第二个轴拼接(从0开始索引)
np.concatenate([grid, grid], axis=1)
Out[56]:
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])

沿着固定维度处理数组时,使用np.vstacknp.hstack函数更简洁:

In [57]:
x = np.array([1,2,3])
grid = np.array([[9,8,7],[6,5,4]])
np.vstack([x, grid])
Out[57]:
array([[1, 2, 3],
       [9, 8, 7],
       [6, 5, 4]])
In [58]:
y = np.array([[99],[99]])
np.hstack([grid, y])
Out[58]:
array([[ 9,  8,  7, 99],
       [ 6,  5,  4, 99]])

与拼接相反的过程是分裂。分裂可以通过np.splitnp.hsplitnp.vsplit函数来实现。

In [60]:
x = [1,2,3,99,99,3,2,1]
x1, x2, x3 = np.split(x, [3,5])
print(x1, x2, x3)
[1 2 3] [99 99] [3 2 1]

值得注意的是N个分裂点会得到N+1个子数组。

In [61]:
grid = np.arange(16).reshape((4,4))
grid
Out[61]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
In [64]:
upper, lower = np.vsplit(grid, [2])
print(upper)
[[0 1 2 3]
 [4 5 6 7]]
In [65]:
print(lower)
[[ 8  9 10 11]
 [12 13 14 15]]
In [66]:
left,right = np.hsplit(grid, [2])
print(left)
[[ 0  1]
 [ 4  5]
 [ 8  9]
 [12 13]]
In [67]:
print(right)
[[ 2  3]
 [ 6  7]
 [10 11]
 [14 15]]

NumPy通用函数

+ : np.add (1+1=2)

- : np.subtract (3-2=1)

- : np.negative (-2)

* : np.multipy (2*3=6)

/ : np.divide (3/2=1.5)

// : np.floor_divide (3//2=1)

** : np.power (2**3=8)

% : np.mod (9%4=1)

In [70]:
x = np.array([-2,-1,0,1,2])
np.abs(x)
Out[70]:
array([2, 1, 0, 1, 2])
In [73]:
theta = np.linspace(0, np.pi, 3)
print("theta = ", theta)
print("sin(theta) = ", np.sin(theta))
print("cos(theta) = ", np.cos(theta))
print("tan(theta) = ", np.tan(theta))
theta =  [0.         1.57079633 3.14159265]
sin(theta) =  [0.0000000e+00 1.0000000e+00 1.2246468e-16]
cos(theta) =  [ 1.000000e+00  6.123234e-17 -1.000000e+00]
tan(theta) =  [ 0.00000000e+00  1.63312394e+16 -1.22464680e-16]
In [74]:
x = [-1,0,1]
print("x = ", x)
print("arcsin(x)=", np.arcsin(x))
print("arccos(x)=", np.arccos(x))
print("arctan(x)=", np.arctan(x))
x =  [-1, 0, 1]
arcsin(x)= [-1.57079633  0.          1.57079633]
arccos(x)= [3.14159265 1.57079633 0.        ]
arctan(x)= [-0.78539816  0.          0.78539816]
In [75]:
x = [1,2,3]
print("x =", x)
print("e^x =", np.exp(x))
print("2^x =", np.exp2(x))
print("3^x =", np.power(3, x))
x = [1, 2, 3]
e^x = [ 2.71828183  7.3890561  20.08553692]
2^x = [2. 4. 8.]
3^x = [ 3  9 27]

聚合

用通用函数的reduce方法对给定的元素和操作重复执行,直到得到单个的结果

注意:在一些特俗情况中,NumPy提供了专用函数(np.sum,np.prod,np.cumsum, np.cumprod),它们也可以实现reduce的功能

In [76]:
x = np.arange(1,6)
In [77]:
x
Out[77]:
array([1, 2, 3, 4, 5])
In [78]:
np.add.reduce(x)
Out[78]:
15
In [79]:
np.multiply.reduce(x)
Out[79]:
120
In [80]:
# 如果需要存储每次计算的中间结果,可以使用accumulate:
np.add.accumulate(x)
Out[80]:
array([ 1,  3,  6, 10, 15])
In [81]:
np.multiply.accumulate(x)
Out[81]:
array([  1,   2,   6,  24, 120])

外积

任何通用函数都可以用outer方法获得两个不同输入数组所有元素对的函数运算结果

In [86]:
x = np.arange(1, 6)
np.multiply.outer(x, x)
Out[86]:
array([[ 1,  2,  3,  4,  5],
       [ 2,  4,  6,  8, 10],
       [ 3,  6,  9, 12, 15],
       [ 4,  8, 12, 16, 20],
       [ 5, 10, 15, 20, 25]])
In [87]:
x = np.array([True, True, False, True])
y = np.array([True, True, True, True])
np.any(x)
Out[87]:
True
In [88]:
np.all(x)
Out[88]:
False
In [89]:
np.all(y)
Out[89]:
True

示例:美国总统身高

In [91]:
import pandas as pd
data = pd.read_csv('/Users/swami/Desktop/PythonDataScienceHandbook-master/notebooks/data/president_heights.csv')
In [92]:
data.head()
Out[92]:
order name height(cm)
0 1 George Washington 189
1 2 John Adams 170
2 3 Thomas Jefferson 189
3 4 James Madison 163
4 5 James Monroe 183
In [94]:
height = np.array(data['height(cm)'])
In [95]:
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn; seaborn.set() #设置绘图风格
In [96]:
plt.hist(height)
plt.title('Height Distribution of US Presidents')
plt.xlabel('height (cm)')
plt.ylabel('number')
Out[96]:
Text(0,0.5,'number')

广播

广播可以简单理解为用于不同大小数组的二进制通用函数(加、减、乘等)的一组规则

In [97]:
a = np.array([0,1,2])
b = np.array([5,5,5])
a + b
Out[97]:
array([5, 6, 7])
In [98]:
a + 5
Out[98]:
array([5, 6, 7])
In [99]:
M = np.ones((3,3))
M
Out[99]:
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
In [100]:
M + a
Out[100]:
array([[1., 2., 3.],
       [1., 2., 3.],
       [1., 2., 3.]])
In [105]:
a = np.arange(3)
b = np.arange(3)[:, np.newaxis]
print(a,'\n')
print(b)
[0 1 2] 

[[0]
 [1]
 [2]]
In [106]:
a + b
Out[106]:
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])

数组归一化

In [110]:
X = np.random.random((10,3))
In [112]:
Xmean = X.mean(0) #沿着第一个维度聚合
Xmean
Out[112]:
array([0.57223962, 0.58909663, 0.45592965])
In [113]:
# 通过广播从X数组的元素中减去这个均值实现归一化
X_centered = X - Xmean
In [114]:
# 进一步核对,看看归一化的数组的均值是否接近0
X_centered.mean(0)
Out[114]:
array([-2.22044605e-17,  8.88178420e-17, -3.33066907e-17])

画一个二维函数

广播的另一个非常有用的地方在于它能基于二维函数现实图像,定义一个函数z=f(x,y),用广播沿着数值区间计算该函数:

In [115]:
x = np.linspace(0,5, 50)
y = np.linspace(0,5, 50)[:, np.newaxis]
z = np.sin(x)**10 + np.cos(10 + y*x)*np.cos(x)
In [116]:
%matplotlib inline
import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', extent=[0,5,0,5], cmap='viridis')
plt.colorbar()
Out[116]:
<matplotlib.colorbar.Colorbar at 0x11d0b5978>

示例:统计下雨天数

In [122]:
rainfall = pd.read_csv('/Users/swami/Desktop/PythonDataScienceHandbook-master/notebooks/data/Seattle2014.csv')['PRCP'].values
In [124]:
inches = rainfall / 254 # 1/10mm -> inches
inches.shape
Out[124]:
(365,)
In [125]:
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn; seaborn.set() #设置绘图风格
In [126]:
plt.hist(inches)
Out[126]:
(array([289.,  25.,  20.,  13.,  10.,   3.,   2.,   2.,   0.,   1.]),
 array([0.        , 0.18385827, 0.36771654, 0.5515748 , 0.73543307,
        0.91929134, 1.10314961, 1.28700787, 1.47086614, 1.65472441,
        1.83858268]),
 <a list of 10 Patch objects>)

比较运算符

== : np.equal

!= : np.not_equal

< : np.less

<= : np.less_equal

> : np.greater

>= : np.greater_equal

In [127]:
rng = np.random.RandomState(0)
x = rng.randint(10, size = (3,4))
x
Out[127]:
array([[5, 0, 3, 3],
       [7, 9, 3, 5],
       [2, 4, 7, 6]])
In [128]:
x < 6
Out[128]:
array([[ True,  True,  True,  True],
       [False, False,  True,  True],
       [ True,  True, False, False]])
In [129]:
# 有多少值小于6?
np.count_nonzero(x < 6)
Out[129]:
8
In [130]:
np.sum(x < 6)
Out[130]:
8
In [131]:
np.sum(x < 6, axis=1)
Out[131]:
array([4, 2, 2])

布尔运算符

& : np.bitwise_and

| : np.bitwise_or

^ : np.bitwise_xor

~ : np.bitwise_not

In [ ]: