numpy笔记-ch04:NumPy 基础: Arrays(数组) 和 Vectorized(矢量) 计算

ch04:NumPy 基础: Arrays(数组) 和 Vectorized(矢量) 计算

 

 

 

NumPy 基础: Arrays(数组) 和 Vectorized(矢量) 计算

In [2]:
%matplotlib inline
In [1]:
from __future__ import division
from numpy.random import randn
import numpy as np
np.set_printoptions(precision=4, suppress=True)
 

The NumPy ndarray: 一种多维数组对象

记ndarray: Numpy 的 data array(Numpy的数据数组)

In [3]:
'np.random.randn(): 返回标准正太分布'
data = randn(2, 3)
In [7]:
print(data)
print(data * 10)
print(data + data)
 
[[ 0.0233  0.5059  0.9233]
 [ 2.257  -0.8867  0.4751]]
[[  0.2333   5.0587   9.233 ]
 [ 22.5703  -8.8669   4.751 ]]
[[ 0.0467  1.0117  1.8466]
 [ 4.5141 -1.7734  0.9502]]
In [10]:
print(data.shape,'  ' ,data.dtype)
 
(2, 3)    float64
 

创建ndarrays

 

从序列型对象中(包括其他数组)创建数组

In [11]:
'接受一切序列类型的对象:包括数组'
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)
arr1
Out[11]:
array([ 6. ,  7.5,  8. ,  0. ,  1. ])
In [25]:
'接受嵌套序列'
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
print(arr2,'\n',
arr2.ndim,'\n',
arr2.shape)
 
[[1 2 3 4]
 [5 6 7 8]] 
 2 
 (2, 4)
In [17]:
arr1.dtype
Out[17]:
dtype('float64')
In [16]:
arr2.dtype
Out[16]:
dtype('int32')
 

从函数中创建数组

In [19]:
np.zeros(10)
Out[19]:
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
In [22]:
np.zeros((3,6))
Out[22]:
array([[ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])
In [44]:
np.empty((4,3,6)) #很多情况下会返回未初始化的垃圾值
Out[44]:
array([[[  2.0207e-321,   8.0469e-315,   2.6877e-321,           nan,
           1.4327e+161,   4.5632e-144],
        [  4.8241e+228,   1.0472e-142,   3.9845e+252,   9.0671e+271,
           7.7935e-143,   1.0306e-113],
        [  1.1379e-094,   6.0310e-154,   6.9631e-077,   7.0665e-096,
           6.0310e-154,   1.8115e-152]],

       [[  8.9421e+130,   6.0135e-154,   3.2425e-086,   1.0509e-153,
           6.0135e-154,   3.2425e-086],
        [  6.0135e-154,   6.9635e-077,   1.1379e-094,   6.0310e-154,
           6.9631e-077,   7.0665e-096],
        [  5.4989e-095,   6.0135e-154,   6.9635e-077,   7.0665e-096,
           6.0310e-154,   6.9631e-077]],

       [[  7.0665e-096,   1.0308e+136,   6.0135e-154,   1.0509e-153,
           6.0135e-154,   3.2425e-086],
        [  1.0509e-153,   6.0135e-154,   6.1274e-154,   8.0924e-153,
           6.9631e-077,   7.0665e-096],
        [  6.0310e-154,   6.9631e-077,   7.1899e+140,   6.1274e-154,
           8.1612e-153,   6.9631e-077]],

       [[  7.0665e-096,   6.0310e-154,   6.9631e-077,   7.1899e+140,
           6.0135e-154,   3.2425e-086],
        [  1.0509e-153,   6.0135e-154,   3.2425e-086,   1.0509e-153,
           4.0736e+223,   6.0135e-154],
        [  6.0310e-154,   6.9631e-077,   7.0665e-096,   6.0310e-154,
           6.9631e-077,   2.9771e+296]]])
In [26]:
np.arange(15)
Out[26]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
 

表4-1:数组创建函数

array 将输入数据(列表、元组、数组或其他序列类型)转换为ndarray。要么推断出dtype,要么显式指定dtpye。默认直接复制输入数据 asarray 将输入转换为ndarray,如果输入本身就是一个ndarray就不进行复制 arange 类似于内置的range,但返回的是一个ndarray而不是列表 ones、ones_like 根据指定的形状和dtype创建一个全1数组。ones_like以另一个数组为参数,并根据其形状和dtpye创建一个全1数组 zeros、zeros_like 类似于ones 和 ones_like,只不过产生的是全0数组而已 empty、empty_like 创建新数组,只分配内存空间但不填充任何值 eye、identity 创建一个正方的N*N单位矩阵(对角线为1,其余为0)

 

ndarrays的数据类型

记dtype: data type

In [46]:
arr1 = np.array([1, 2, 3], dtype=np.float64)
arr2 = np.array([1, 2, 3], dtype=np.int32)
arr1.dtype
Out[46]:
dtype('float64')
In [45]:
arr2.dtype
Out[45]:
dtype('int32')
 

通过astype方法转换dtype

In [47]:
'整数转换成浮点数'
arr = np.array([1, 2, 3, 4, 5])
arr.dtype
Out[47]:
dtype('int32')
In [48]:
float_arr = arr.astype(np.float64) #整数转换成浮点数
float_arr.dtype
Out[48]:
dtype('float64')
In [49]:
'浮点数转换成整数,小数部分会被截断'
arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
arr
Out[49]:
array([  3.7,  -1.2,  -2.6,   0.5,  12.9,  10.1])
In [50]:
arr.astype(np.int32)
Out[50]:
array([ 3, -1, -2,  0, 12, 10])
In [3]:
'字符串数组全部是数字的话可以转化成数值形式:否则会抛出TypeError异常'
numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
numeric_strings.astype(float)
Out[3]:
array([  1.25,  -9.6 ,  42.  ])
In [53]:
'转换成另一个数组的 dtype'
int_array = np.arange(10)
calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64)
int_array.astype(calibers.dtype)
Out[53]:
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])
In [55]:
'简洁类型代码表示 dtype'
empty_uint32 = np.empty(8, dtype='u4')
empty_uint32
Out[55]:
array([1, 2, 3, 4, 5, 6, 7, 8], dtype=uint32)
 

表4-2:Numpy的数据类型

类型 类型代码 说明 int8、uint8 i1、u1 有符号和无符号的8位(1个字节)整型 int16、uint16 i2、u2 有符号和无符号的16位(2个字节)整型 int32、uint32 i3、u3 有符号和无符号的32位(4个字节)整型 int64、uint64 i4、u4 有符号和无符号的64位(8个字节)整型 float16 f2 半精度浮点数 float32 f4或f 标准的单精度浮点数。与C的float兼容 float64 f8或d 标准的双精度浮点数。与C的double和Python的float对象兼容 float128 f16或g 扩展精度浮点数 complex64、complex128、complex256 c8或c16或c32 分别用两个32位、64位或128位浮点数表示的复数 bool ? 存储True和False值的布尔类型 object O Python对象类型 string_ S 固定长度的字符串类型(每个字符1个字节)。例如,要创建一个长度为10的字符串,应使用S10 unicode_ U 固定长度的Unicode类型(字节数由平台决定)。跟字符串的定义方式一样(如U10)

 

数组和标量之间的运算

In [5]:
'大小相等的数组之间的任何运算都会将运算应用到元素级'
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
arr
Out[5]:
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
In [6]:
arr * arr
Out[6]:
array([[  1.,   4.,   9.],
       [ 16.,  25.,  36.]])
In [7]:
arr - arr
Out[7]:
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
In [11]:
'数组与标量之间的运算也是元素级别的运算'
1 / arr
Out[11]:
array([[ 1.    ,  0.5   ,  0.3333],
       [ 0.25  ,  0.2   ,  0.1667]])
In [10]:
arr ** 0.5
Out[10]:
array([[ 1.    ,  1.4142,  1.7321],
       [ 2.    ,  2.2361,  2.4495]])
 

基本的索引和切片

In [12]:
arr = np.arange(10)
arr
Out[12]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [13]:
arr[5]
Out[13]:
5
In [14]:
arr[5:8]
Out[14]:
array([5, 6, 7])
In [23]:
'通过切片赋值修改数组'
arr[5:8] = 12
arr
Out[23]:
array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])
In [21]:
'切片传递的是指针,对切片传递的数组修改会影响到原数组'
arr_slice = arr[5:8]
arr_slice[1] = 12345
arr
Out[21]:
array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,     9])
In [22]:
arr_slice[:] = 64
arr
Out[22]:
array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])
In [24]:
'高维数组的索引'
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
Out[24]:
array([7, 8, 9])
In [25]:
#一下两种方式索引等价
arr2d[0][2]
arr2d[0, 2]
Out[25]:
3
In [26]:
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr3d 
Out[26]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
In [27]:
arr3d[0]
Out[27]:
array([[1, 2, 3],
       [4, 5, 6]])
In [28]:
'标量值和数组都可以被赋值给arr3d[0]'
old_values = arr3d[0].copy()
arr3d[0] = 42
arr3d
Out[28]:
array([[[42, 42, 42],
        [42, 42, 42]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
In [33]:
arr3d[0] = old_values
arr3d
Out[33]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
In [34]:
arr3d[1, 0]
Out[34]:
array([7, 8, 9])
 

切片索引

In [37]:
'数组的切片语法类似于Python的列表'
arr[1:6]
Out[37]:
array([ 1,  2,  3,  4, 12])
In [39]:
arr2d
Out[39]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
In [40]:
'默认第一个轴切片'
arr2d[:2]
Out[40]:
array([[1, 2, 3],
       [4, 5, 6]])
In [41]:
'两个轴:同时切片'
arr2d[:2, 1:]
Out[41]:
array([[2, 3],
       [5, 6]])
In [46]:
arr2d[:, :1]
Out[46]:
array([[1],
       [4],
       [7]])
In [44]:
'两个轴:索引与切片混合'
arr2d[1, :2]
Out[44]:
array([4, 5])
In [45]:
arr2d[2, :1]
Out[45]:
array([7])
In [48]:
'切片赋值'
arr2d[:2, 1:] = 0
arr2d
Out[48]:
array([[1, 0, 0],
       [4, 0, 0],
       [7, 8, 9]])
 

布尔型索引

In [50]:
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = randn(7, 4)
names
Out[50]:
array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], 
      dtype='<U4')
In [51]:
data
Out[51]:
array([[ 0.209 , -1.0301, -0.8019, -0.9262],
       [ 1.0913, -1.1727,  1.4343, -0.6793],
       [ 1.659 , -0.7472, -0.9665, -0.0124],
       [-0.8069, -1.4561,  0.3145, -0.1321],
       [ 1.4995, -1.3718,  0.4757,  0.2757],
       [-0.5362, -0.2394,  1.9615, -0.5591],
       [-0.7974,  0.8115, -0.8535, -1.1512]])
In [53]:
'数组的比较运算也是矢量化的(即运算到元素)'
names == 'Bob'
Out[53]:
array([ True, False, False,  True, False, False, False], dtype=bool)
In [56]:
'布尔型索引'
data[names == 'Bob']
Out[56]:
array([[ 0.209 , -1.0301, -0.8019, -0.9262],
       [-0.8069, -1.4561,  0.3145, -0.1321]])
In [61]:
'布尔型索引与切片或索引混合'
data[names == 'Bob', 2:]
Out[61]:
array([[-0.8019, -0.9262],
       [ 0.3145, -0.1321]])
In [62]:
data[names == 'Bob', 3]
Out[62]:
array([-0.9262, -0.1321])
In [63]:
'!= 与 -'
names != 'Bob'
Out[63]:
array([False,  True,  True, False,  True,  True,  True], dtype=bool)
In [69]:
data[-(names == 'Bob')] # - 过时 请使用 ~  或者 logical_not function
 
D:\zwPython\py35\python-3.5.1.amd64\lib\site-packages\ipykernel\__main__.py:1: DeprecationWarning: numpy boolean negative, the `-` operator, is deprecated, use the `~` operator or the logical_not function instead.
  if __name__ == '__main__':
Out[69]:
array([[ 1.0913, -1.1727,  1.4343, -0.6793],
       [ 1.659 , -0.7472, -0.9665, -0.0124],
       [ 1.4995, -1.3718,  0.4757,  0.2757],
       [-0.5362, -0.2394,  1.9615, -0.5591],
       [-0.7974,  0.8115, -0.8535, -1.1512]])
In [70]:
data[~(names == 'Bob')] # - 过时 请使用 ~  或者 logical_not function
Out[70]:
array([[ 1.0913, -1.1727,  1.4343, -0.6793],
       [ 1.659 , -0.7472, -0.9665, -0.0124],
       [ 1.4995, -1.3718,  0.4757,  0.2757],
       [-0.5362, -0.2394,  1.9615, -0.5591],
       [-0.7974,  0.8115, -0.8535, -1.1512]])
In [71]:
data[(names != 'Bob')] # - 过时 请使用 ~  或者 logical_not function
Out[71]:
array([[ 1.0913, -1.1727,  1.4343, -0.6793],
       [ 1.659 , -0.7472, -0.9665, -0.0124],
       [ 1.4995, -1.3718,  0.4757,  0.2757],
       [-0.5362, -0.2394,  1.9615, -0.5591],
       [-0.7974,  0.8115, -0.8535, -1.1512]])
In [72]:
mask = (names == 'Bob') | (names == 'Will')
mask
Out[72]:
array([ True, False,  True,  True,  True, False, False], dtype=bool)
In [73]:
data[mask]
Out[73]:
array([[ 0.209 , -1.0301, -0.8019, -0.9262],
       [ 1.659 , -0.7472, -0.9665, -0.0124],
       [-0.8069, -1.4561,  0.3145, -0.1321],
       [ 1.4995, -1.3718,  0.4757,  0.2757]])
In [74]:
'布尔类型索引赋值'
data[data < 0] = 0
data
Out[74]:
array([[ 0.209 ,  0.    ,  0.    ,  0.    ],
       [ 1.0913,  0.    ,  1.4343,  0.    ],
       [ 1.659 ,  0.    ,  0.    ,  0.    ],
       [ 0.    ,  0.    ,  0.3145,  0.    ],
       [ 1.4995,  0.    ,  0.4757,  0.2757],
       [ 0.    ,  0.    ,  1.9615,  0.    ],
       [ 0.    ,  0.8115,  0.    ,  0.    ]])
In [75]:
data[names != 'Joe'] = 7
data
Out[75]:
array([[ 7.    ,  7.    ,  7.    ,  7.    ],
       [ 1.0913,  0.    ,  1.4343,  0.    ],
       [ 7.    ,  7.    ,  7.    ,  7.    ],
       [ 7.    ,  7.    ,  7.    ,  7.    ],
       [ 7.    ,  7.    ,  7.    ,  7.    ],
       [ 0.    ,  0.    ,  1.9615,  0.    ],
       [ 0.    ,  0.8115,  0.    ,  0.    ]])
 

花式索引:利用整数数组进行索引

注:花式索引传递的不是指针,而是复制,注意这点与切片的不同

In [76]:
arr = np.empty((8, 4))
for i in range(8):
    arr[i] = i
arr
Out[76]:
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 [77]:
arr[[4, 3, 0, 6]]
Out[77]:
array([[ 4.,  4.,  4.,  4.],
       [ 3.,  3.,  3.,  3.],
       [ 0.,  0.,  0.,  0.],
       [ 6.,  6.,  6.,  6.]])
In [78]:
arr[[-3, -5, -7]]
Out[78]:
array([[ 5.,  5.,  5.,  5.],
       [ 3.,  3.,  3.,  3.],
       [ 1.,  1.,  1.,  1.]])
In [79]:
# more on reshape in Chapter 12
arr = np.arange(32).reshape((8, 4))
arr
Out[79]:
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 [80]:
'花式多维索引对应具体值,非区域'
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
Out[80]:
array([ 4, 23, 29, 10])
In [81]:
'单维索引 + 切片:获取一个区域'
arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
Out[81]:
array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])
In [82]:
'利用函数 ix_ 通过索引获取区域值'
arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])]
Out[82]:
array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])
 

转置和轴对换

In [84]:
arr = np.arange(15).reshape((3, 5))
arr
Out[84]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
In [85]:
arr.T # arr转置
Out[85]:
array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])
In [86]:
arr = np.random.randn(6, 3)
np.dot(arr.T, arr) # dot 计算矩阵内积 arr.T * arrr
Out[86]:
array([[ 2.9082, -0.8139,  1.3435],
       [-0.8139,  2.4252,  0.4285],
       [ 1.3435,  0.4285,  2.9309]])
In [87]:
arr = np.arange(16).reshape((2, 2, 4))
arr
Out[87]:
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])
In [88]:
arr.transpose((1, 0, 2)) # 1, 0, 2 是轴编号
Out[88]:
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])
In [89]:
arr
arr.swapaxes(1, 2) #特定轴进行转置,接受轴编号
Out[89]:
array([[[ 0,  4],
        [ 1,  5],
        [ 2,  6],
        [ 3,  7]],

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]]])
 

通用函数:快速的元素级数组函数

In [90]:
'一元ufunc举例'
arr = np.arange(10)
np.sqrt(arr)
Out[90]:
array([ 0.    ,  1.    ,  1.4142,  1.7321,  2.    ,  2.2361,  2.4495,
        2.6458,  2.8284,  3.    ])
In [91]:
np.exp(arr)
Out[91]:
array([    1.    ,     2.7183,     7.3891,    20.0855,    54.5982,
         148.4132,   403.4288,  1096.6332,  2980.958 ,  8103.0839])
In [5]:
'二元ufunc举例'
x = randn(8)
y = randn(8)
x
Out[5]:
array([ 1.5215,  0.4638, -0.6287,  0.328 ,  0.6725, -0.4478,  0.6229,
       -0.5629])
In [6]:
y
Out[6]:
array([ 0.6372,  0.3902, -0.7278, -1.6626, -0.7102,  1.1675,  0.2137,
        0.7891])
In [7]:
np.maximum(x, y) # element-wise maximum
Out[7]:
array([ 1.5215,  0.4638, -0.6287,  0.328 ,  0.6725,  1.1675,  0.6229,
        0.7891])
In [93]:
'返回多个数组的ufunc举例'
arr = randn(7) * 5
arr
Out[93]:
array([ 11.9872,   7.8733,  -0.6205, -10.9722,  -1.4553,  -0.6672,   0.0211])
In [94]:
'np.modf(): python内置函数divmod的矢量化版本'
np.modf(arr)
Out[94]:
(array([ 0.9872,  0.8733, -0.6205, -0.9722, -0.4553, -0.6672,  0.0211]),
 array([ 11.,   7.,  -0., -10.,  -1.,  -0.,   0.]))
 

表4-3:一元ufunc(类方法,非实例化方法)简介:

abs、fabs 计算整数、浮点数或复数的绝对值。对于非复数值,可以使用更快的fabs sqrt 计算各元素的平方根。相当于arr**0.5 square 计算各元素的平方。相当于arr**2 exp 计算各元素的指数e^x log,log10,log2,log1p 分别计算自然对数(底数为e),地数为10的log,底数为2的log,ln(1+x) sign 计算各元素的正负号:1(正数)、0(零)、-1(负数) ceil 计算各元素的ceiling值,即大于等于该值的最小整数 floor 计算个元素的floor值,级小于等于该值的最大整数 rint 将各元素值四舍五入到最接近的整数,保留dtype modf 将数组的小数和整数部分以两个独立数组的形式返回 isnan 返回布尔型数组 isfinite,isinf 分别返回一个表示‘哪些元素是有穷的(非inf,非NaN)’或‘哪些元素是无穷的’的布尔型数组 cos,cosh,sin,sinh,tan,tanh 普通型和双曲线型三角函数 arccos,arccosh,arcsin,arcsinh,arctan,arctanh 反三角函数 logical_not 计算各元素not x 的真值。相当于 -arr

 

表4-4:二元unfunc的简介:

add 将数组中对应的元素相加 subtract 从第一个数组中减去第二个数组中的元素 multiply 数组元素相乘 divide,floor_divide 除法或向下圆整除法(丢弃余数) power 对第一个数组中的元素A,根据第二个数组中的相应元素B,计算A\*\*B 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 执行元素级的真值逻辑运算。相当于中缀运算符&,|,^

 

利用数组进行数据处理

In [10]:
points = np.arange(-5, 5, 0.01) # 1000 equally spaced points
'xs,ys是1000*1000的矩阵'
xs, ys = np.meshgrid(points, points)
xs.T == ys
Out[10]:
array([[ True,  True,  True, ...,  True,  True,  True],
       [ True,  True,  True, ...,  True,  True,  True],
       [ True,  True,  True, ...,  True,  True,  True],
       ..., 
       [ True,  True,  True, ...,  True,  True,  True],
       [ True,  True,  True, ...,  True,  True,  True],
       [ True,  True,  True, ...,  True,  True,  True]], dtype=bool)
In [11]:
ys
Out[11]:
array([[-5.  , -5.  , -5.  , ..., -5.  , -5.  , -5.  ],
       [-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],
       [-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],
       ..., 
       [ 4.97,  4.97,  4.97, ...,  4.97,  4.97,  4.97],
       [ 4.98,  4.98,  4.98, ...,  4.98,  4.98,  4.98],
       [ 4.99,  4.99,  4.99, ...,  4.99,  4.99,  4.99]])
In [9]:
xs
Out[9]:
array([[-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       ..., 
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99]])
In [12]:
from matplotlib.pyplot import imshow, title
In [13]:
import matplotlib.pyplot as plt
z = np.sqrt(xs ** 2 + ys ** 2)
z
Out[13]:
array([[ 7.0711,  7.064 ,  7.0569, ...,  7.0499,  7.0569,  7.064 ],
       [ 7.064 ,  7.0569,  7.0499, ...,  7.0428,  7.0499,  7.0569],
       [ 7.0569,  7.0499,  7.0428, ...,  7.0357,  7.0428,  7.0499],
       ..., 
       [ 7.0499,  7.0428,  7.0357, ...,  7.0286,  7.0357,  7.0428],
       [ 7.0569,  7.0499,  7.0428, ...,  7.0357,  7.0428,  7.0499],
       [ 7.064 ,  7.0569,  7.0499, ...,  7.0428,  7.0499,  7.0569]])
In [19]:
%matplotlib  inline
plt.imshow(z, cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
Out[19]:
<matplotlib.text.Text at 0xc9337f0>
 
In [30]:
%matplotlib notebook
plt.plot()
plt.imshow(z, cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
 
 
 
Out[30]:
<matplotlib.text.Text at 0xdfe0320>
In [ ]:
plt.draw() #redraw 功能,适用于已经更新了数据,但是没有更新图像的功能
 

将条件逻辑表述为数组运算

In [35]:
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, True, False])
In [36]:
'纯Python的三元表达式'
result = [(x if c else y)
          for x, y, c in zip(xarr, yarr, cond)]
result
#纯Python完成的两个缺陷:
#  1.运算速度慢
#  2.无法适用于多维数组
Out[36]:
[1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]
In [37]:
'np.where运算:第二个和低三个不必是数组,也可以是表达式'
result = np.where(cond, xarr*10, yarr)
result
Out[37]:
array([ 11. ,   2.2,  13. ,  14. ,   2.5])
In [123]:
arr = randn(4, 4)
arr
Out[123]:
array([[ 0.5268, -0.3649,  0.6623, -0.359 ],
       [ 0.6939,  1.8307, -0.4546,  0.4498],
       [-0.8319, -1.6706, -0.927 , -0.6308],
       [-0.3148, -0.4626, -0.3786,  0.0024]])
In [124]:
np.where(arr > 0, 2, -2) # arr 所有正值替换为 2,所有负值替换为 -2
Out[124]:
array([[ 2, -2,  2, -2],
       [ 2,  2, -2,  2],
       [-2, -2, -2, -2],
       [-2, -2, -2,  2]])
In [125]:
np.where(arr > 0, 2, arr) # 仅仅设置正值为 2
Out[125]:
array([[ 2.    , -0.3649,  2.    , -0.359 ],
       [ 2.    ,  2.    , -0.4546,  2.    ],
       [-0.8319, -1.6706, -0.927 , -0.6308],
       [-0.3148, -0.4626, -0.3786,  2.    ]])
In [ ]:
# Not to be executed

result = []
for i in range(n):
    if cond1[i] and cond2[i]:
        result.append(0)
    elif cond1[i]:
        result.append(1)
    elif cond2[i]:
        result.append(2)
    else:
        result.append(3)

'上面for循环可以改写成:'
np.where(cond1 & cond2, 0,
         np.where(cond1, 1,
                  np.where(cond2, 2, 3)))

'也可以改写成:'
result = 1 * cond1 + 2 * cond2 + 3 * -(cond1 | cond2)
 

数学和统计方法

In [39]:
'聚合性:返回结果为标量,包括实例化调用和顶级Numpy数组的调用两种调用方法'
arr = np.random.randn(5, 4) # normally-distributed data
arr.mean() #实例化调用
Out[39]:
0.22928353772290433
In [40]:
np.mean(arr) #顶级Numpy数组调用:两者结果一致
Out[40]:
0.22928353772290433
In [43]:
arr
Out[43]:
array([[ 0.9299,  0.7001,  0.472 , -1.0974],
       [-0.4504,  0.2372, -0.247 ,  0.9276],
       [ 1.0417,  0.712 , -0.8957, -0.5762],
       [ 1.524 , -1.192 , -0.6325, -0.3867],
       [-0.5465,  1.8381,  1.7573,  0.4701]])
In [41]:
arr.sum()
Out[41]:
4.5856707544580866
In [42]:
# '对 轴 进行数学运算'
arr.mean(axis=1)
Out[42]:
array([ 0.2511,  0.1168,  0.0705, -0.1718,  0.8798])
In [44]:
arr.sum(0) #arr.sum(axis=0)
Out[44]:
array([ 2.4989,  2.2954,  0.4541, -0.6627])
In [130]:
'非聚合性:返回数组,如累计计算'
arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr.cumsum(0) #累计加
Out[130]:
array([[ 0,  1,  2],
       [ 3,  5,  7],
       [ 9, 12, 15]], dtype=int32)
In [131]:
arr.cumprod(1) #累计乘
Out[131]:
array([[  0,   0,   0],
       [  3,  12,  60],
       [  6,  42, 336]], dtype=int32)
 

表4-5:基本数组统计方法(实例化方法+顶级Numpy方法):

sum 对数组中全部或某轴向的元素求和。零长度的数组的sum为0 mean 算术平均数。零长度的数组的mean为NaN std,var 分别为标准差和方差,自由度可调(默认为n) min,max 最大值和最小值 argmin,argmax 分别为最大和最小元素的索引 cumsum 所有元素的累计和 cumprod 所有元素的累计积

 

布尔型数组的方法

In [45]:
arr = randn(100)
arr>0
Out[45]:
array([ True, False,  True, False,  True, False,  True, False,  True,
        True, False,  True,  True,  True,  True,  True,  True,  True,
       False, False, False,  True,  True, False, False,  True,  True,
       False,  True,  True, False, False,  True,  True,  True, False,
        True, False,  True, False,  True,  True, False,  True, False,
        True,  True,  True, False,  True,  True, False, False, False,
       False, False,  True,  True, False,  True,  True, False, False,
       False, False,  True, False, False, False,  True,  True,  True,
       False, False,  True,  True, False,  True, False, False, False,
       False,  True,  True,  True,  True,  True,  True, False,  True,
       False, False, False,  True,  True, False,  True,  True, False, False], dtype=bool)
In [46]:
(arr > 0).sum() # 正值的个数
Out[46]:
54
In [133]:
bools = np.array([False, False, True, False])
bools.any()
Out[133]:
True
In [134]:
bools.all()
Out[134]:
False
 

排序

In [135]:
arr = randn(8)
arr
Out[135]:
array([-1.0364,  0.3521,  0.6297,  1.7804, -0.5302, -0.6343,  0.6919,
       -0.0344])
In [139]:
arr2 = randn(8)
arr2
Out[139]:
array([ 3.1761,  0.8682,  1.6253,  2.1243, -0.1286,  0.4107,  0.3398,
       -1.5606])
In [136]:
'实例化排序改变原始数组'
arr.sort()
arr
Out[136]:
array([-1.0364, -0.6343, -0.5302, -0.0344,  0.3521,  0.6297,  0.6919,
        1.7804])
In [142]:
'顶层排序np.sort是返回排序后的副本'
print(np.sort(arr2))
print(arr2)
 
[-1.5606 -0.1286  0.3398  0.4107  0.8682  1.6253  2.1243  3.1761]
[ 3.1761  0.8682  1.6253  2.1243 -0.1286  0.4107  0.3398 -1.5606]
In [137]:
'多维数组排序'
arr = randn(5, 3)
arr
Out[137]:
array([[ 1.3326,  1.382 , -1.1077],
       [ 1.4384,  0.8898, -1.09  ],
       [ 0.5606, -0.4534, -0.2169],
       [-0.8617,  1.1073,  0.4634],
       [ 0.3837,  0.5689,  2.3009]])
In [138]:
arr.sort(1)
arr
Out[138]:
array([[-1.1077,  1.3326,  1.382 ],
       [-1.09  ,  0.8898,  1.4384],
       [-0.4534, -0.2169,  0.5606],
       [-0.8617,  0.4634,  1.1073],
       [ 0.3837,  0.5689,  2.3009]])
In [64]:
'简单的计算数组分位数的方法'
large_arr = randn(100)
large_arr.sort()
large_arr
Out[64]:
array([-1.8535, -1.6919, -1.6063, -1.5649, -1.5617, -1.3876, -1.3447,
       -1.3038, -1.2427, -1.137 , -1.1075, -1.0948, -1.0805, -1.0332,
       -1.0213, -0.9893, -0.9811, -0.94  , -0.904 , -0.8981, -0.8858,
       -0.8185, -0.7944, -0.782 , -0.7771, -0.7473, -0.6766, -0.6143,
       -0.5524, -0.501 , -0.4556, -0.4279, -0.401 , -0.3845, -0.3765,
       -0.3067, -0.3056, -0.278 , -0.2723, -0.2593, -0.2109, -0.2059,
       -0.2058, -0.1915, -0.1805, -0.1476, -0.11  , -0.1096, -0.0703,
       -0.052 , -0.0202,  0.1172,  0.1496,  0.1539,  0.1547,  0.1578,
        0.2047,  0.2266,  0.2333,  0.2402,  0.2736,  0.2947,  0.3474,
        0.3503,  0.4094,  0.4462,  0.461 ,  0.5132,  0.5315,  0.5336,
        0.5592,  0.6079,  0.6129,  0.6285,  0.6287,  0.6697,  0.7224,
        0.7302,  0.7518,  0.755 ,  0.7589,  0.7972,  0.8092,  0.8354,
        0.8526,  0.8671,  0.896 ,  0.965 ,  0.9983,  1.0056,  1.0354,
        1.0808,  1.1001,  1.1084,  1.191 ,  1.3467,  1.4201,  1.4552,
        1.5541,  3.0101])
In [65]:
large_arr[int(0.05 * len(large_arr))] # 5% quantile
Out[65]:
-1.3875845013557133
 

唯一化以及其他的集合逻辑

In [143]:
'np.unique:返回数组集合后的排序'
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
np.unique(names)
Out[143]:
array(['Bob', 'Joe', 'Will'], 
      dtype='<U4')
In [144]:
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
np.unique(ints)
Out[144]:
array([1, 2, 3, 4])
In [145]:
'等价的Python代码:'
sorted(set(names))
Out[145]:
['Bob', 'Joe', 'Will']
In [146]:
'np.inld:成员资格测试'
values = np.array([6, 0, 0, 3, 2, 5, 6])
np.in1d(values, [2, 3, 6])
Out[146]:
array([ True, False, False,  True,  True, False,  True], dtype=bool)
 

表4-6 数组的集合运算

unique(x) 计算x中的唯一元素,并返回有序结果 intersect1d(x,y) 计算x和y的公共元素,并返回有序结果 union1d(x,y) 计算x和y的并集,并返回有序结果 in1d(x,y) 得到一个表示‘x的元素是否包含于y’的布尔型数组 setdiff(x,y) 集合的差,级元素在x中且不在y中 setxor1d(x,y) 集合的对称差,即存在于一个数组中但不同时存在两个数组中的元素

 

数组的文件输入和输出

 

以二进制格式存储数组到硬盘 np.save, np.savez, np.load

In [149]:
arr = np.arange(10)
np.save('some_array', arr) # 会自动添加 .npy 后缀
In [150]:
np.load('some_array.npy')
Out[150]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [151]:
'保存多个数组 .npz'
np.savez('array_archive.npz', a=arr, b=arr)
In [152]:
'读取 .npz 格式:类似字典的形式访问。'
arch = np.load('array_archive.npz')
arch['b']
Out[152]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [155]:
!del some_array.npy
!del array_archive.npz
 
找不到 D:\zwPython\py35\notebooks\Python for Data Analysis\some_array.npy
 
D:\zwPython\py35\notebooks\Python for Data Analysis\array_archive.npz
 
另一个程序正在使用此文件,进程无法访问。
 

存取文本文件

In [164]:
np.savetxt('ex3.txt', randn(4,5), delimiter=',')
!type ex3.txt
 
-7.365324376564752473e-01,6.413298173823187565e-01,-4.396434456240548294e-01,1.019058595754426255e+00,-4.149508555326596876e-02
8.985819818115804436e-01,8.039339701972231245e-02,-1.818911733805127051e+00,-4.556034411164375242e-01,-1.165052843425584905e+00
8.387190145109990613e-01,-8.982753176952398833e-02,-8.716606307035092982e-01,5.744167826614471339e-01,-2.324540014174401314e-01
1.653980311738668885e+00,-8.052169189188184140e-01,1.138022879943320076e+00,1.647513234667192128e+00,-9.407690972020853470e-01
In [165]:
arr = np.loadtxt('ex3.txt', delimiter=',')
arr
Out[165]:
array([[-0.7365,  0.6413, -0.4396,  1.0191, -0.0415],
       [ 0.8986,  0.0804, -1.8189, -0.4556, -1.1651],
       [ 0.8387, -0.0898, -0.8717,  0.5744, -0.2325],
       [ 1.654 , -0.8052,  1.138 ,  1.6475, -0.9408]])
 

线性代数

In [166]:
x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
x
Out[166]:
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
In [167]:
y
Out[167]:
array([[  6.,  23.],
       [ -1.,   7.],
       [  8.,   9.]])
In [168]:
x.dot(y)  # 等于 np.dot(x, y)
Out[168]:
array([[  28.,   64.],
       [  67.,  181.]])
In [169]:
np.dot(x, np.ones(3))
Out[169]:
array([  6.,  15.])
In [171]:
np.random.seed(12345)
In [172]:
from numpy.linalg import inv, qr
X = randn(5, 5)
mat = X.T.dot(X)
inv(mat)
Out[172]:
array([[ 3.0361, -0.1808, -0.6878, -2.8285, -1.1911],
       [-0.1808,  0.5035,  0.1215,  0.6702,  0.0956],
       [-0.6878,  0.1215,  0.2904,  0.8081,  0.3049],
       [-2.8285,  0.6702,  0.8081,  3.4152,  1.1557],
       [-1.1911,  0.0956,  0.3049,  1.1557,  0.6051]])
In [173]:
mat.dot(inv(mat))
Out[173]:
array([[ 1.,  0.,  0.,  0., -0.],
       [ 0.,  1., -0.,  0.,  0.],
       [ 0., -0.,  1.,  0.,  0.],
       [ 0., -0., -0.,  1., -0.],
       [ 0.,  0.,  0.,  0.,  1.]])
In [174]:
q, r = qr(mat)
r
Out[174]:
array([[ -6.9271,   7.389 ,   6.1227,  -7.1163,  -4.9215],
       [  0.    ,  -3.9735,  -0.8671,   2.9747,  -5.7402],
       [  0.    ,   0.    , -10.2681,   1.8909,   1.6079],
       [  0.    ,   0.    ,   0.    ,  -1.2996,   3.3577],
       [  0.    ,   0.    ,   0.    ,   0.    ,   0.5571]])
 

表4-7:常用的numpy.linalg函数

diag 以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0) dot 矩阵乘法 trace 计算对角线元素之和 det 计算矩阵行列式 eig 计算方针的特征值和特征向量 inv 计算方阵的逆 pinv 计算矩阵的Moore-Penrose伪逆 qr 计算QR分解 svd 计算奇异值分解(SVD) solve 解线性方程组Ax=b,其中A为一个方阵 lstsq 计算Ax=b的最小二乘解

 

随机数生成

In [175]:
samples = np.random.normal(size=(4, 4))
samples
Out[175]:
array([[ 0.1241,  0.3026,  0.5238,  0.0009],
       [ 1.3438, -0.7135, -0.8312, -2.3702],
       [-1.8608, -0.8608,  0.5601, -1.2659],
       [ 0.1198, -1.0635,  0.3329, -2.3594]])
In [180]:
from random import normalvariate
N = 1000000
%timeit samples = [normalvariate(0, 1) for i in range(N)]
 
1 loop, best of 3: 1.77 s per loop
In [179]:
'np.random比Python内置的random模块运行速度快'
%timeit np.random.normal(size=N)
 
10 loops, best of 3: 49.1 ms per loop
 

表4-8:部分numpy.random函数

seed 确定随机数数生成器的种子 permutation 返回一个序列的随机排列或返回一个随机排列的范围 shuffle 对一个序列就地随机排列 rand 产生均匀分布的样本值 randint 从给定的上下限范围内随机选取整数 randn 产生正态分布(平均值为0,标准差为1)的样本值,类似于MATLAB接口 binomial 产生二项分布的样本值 normal 产生正态分布(高斯分布)的样本值 beta 产生beta分布的样本值 chisquare 产生卡方分布的样本值 gamma 产生Gamma分布的样本值 uniform 产生在[0,1)中均匀分布的样本值

 

随机漫步的案例

In [185]:
import matplotlib as plt
import random
position = 0
walk = [position]
steps = 1000
for i in range(steps):
    step = 1 if random.randint(0, 1) else -1
    position += step
    walk.append(position)
In [ ]:
np.random.seed(12345)
In [188]:
'np.random的随机漫步等价形式'
nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum()
walk.min()
Out[188]:
-59
In [189]:
walk.max()
Out[189]:
5
In [191]:
'本次随机漫步多久才能举例初始点10个位置:(第一个True就是最大值)'
(np.abs(walk) >= 10).argmax() #np.argmax :返回某一轴上最大值的索引,不选择轴则默认以一维数组处理
Out[191]:
105
 

一次模拟多个随机漫步

In [192]:
nwalks = 5000
nsteps = 1000
draws = np.random.randint(0, 2, size=(nwalks, nsteps)) # 0 or 1
steps = np.where(draws > 0, 1, -1)
walks = steps.cumsum(1)
walks
Out[192]:
array([[ -1,  -2,  -3, ...,  66,  67,  68],
       [  1,   2,   3, ..., -32, -31, -30],
       [ -1,   0,   1, ...,   4,   3,   2],
       ..., 
       [ -1,  -2,  -1, ...,  50,  51,  50],
       [ -1,  -2,  -1, ..., -30, -29, -30],
       [  1,   2,   1, ...,  26,  27,  28]], dtype=int32)
In [193]:
walks.max()
Out[193]:
115
In [194]:
walks.min()
Out[194]:
-124
In [195]:
'计算30或-30的最小穿越时间'
hits30 = (np.abs(walks) >= 30).any(1)
hits30
Out[195]:
array([ True,  True, False, ...,  True,  True,  True], dtype=bool)
In [196]:
hits30.sum() # Number that hit 30 or -30
Out[196]:
3403
In [208]:
'穿越30所走的步数的集合'
crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1)
crossing_times
Out[208]:
array([149, 803, 345, ..., 161, 863, 733], dtype=int64)
In [207]:
crossing_times.mean()
Out[207]:
503.83220687628562
In [210]:
'其他方式获得漫步数据:如normal获得指定均值和标准差的正态分布数据'
steps = np.random.normal(loc=0, scale=0.25,
                         size=(nwalks, nsteps))
steps
Out[210]:
array([[-0.032 , -0.2901, -0.3238, ..., -0.018 ,  0.0354,  0.2228],
       [ 0.3685, -0.2614, -0.1126, ..., -0.1044,  0.0884, -0.1655],
       [ 0.0073,  0.0326,  0.1874, ...,  0.1655,  0.0416,  0.0736],
       ..., 
       [-0.1857, -0.434 , -0.3966, ...,  0.2735, -0.0643,  0.1757],
       [ 0.5718, -0.0634,  0.1758, ..., -0.3433, -0.5486, -0.2677],
       [-0.1065, -0.3775,  0.0041, ..., -0.106 , -0.0479, -0.1622]])
In [ ]:
 
posted @ 2017-04-02 17:50  she35  阅读(250)  评论(0)    收藏  举报