numpy数组和矢量运算03

numpy 基础:数组和矢量运算

xiaoyao

NumPy是在⼀个连续的内存块中存储数据,独⽴于其他Python内置对象。NumPy的C语⾔编写的算法库可以操作内存,⽽不必进⾏类型检查或其它前期⼯作。⽐起Python的内置序列,NumPy数组使⽤的内存更少。NumPy可以在整个数组上执⾏复杂的计算,⽽不需要Python的for循环。

# 导入packages
import numpy as np

np.random.seed(12345)

import matplotlib.pyplot as plt

plt.rc('figure', figsize=(10, 6))
np.set_printoptions(precision=4, suppress=True)

import warnings 
warnings.filterwarnings('ignore')
# 为了显示出性能的差异,这里建立一个包含一百万整数的数组,以及一个等价的python列表
import numpy as np
my_arr = np.arange(1000000)
my_list = list(range(1000000))
# my_arr, my_list
%time for _ in range(10): my_arr2 = my_arr * 2
%time for _ in range(10): my_list2 = [x * 2 for x in my_list]
# 各个序列分别乘以2
Wall time: 19.5 ms
Wall time: 737 ms

可以看到,基于numpy的算法,实际上比纯python块10到100倍数,甚至更快,而且使用的内存更少

ndarray:一种多维数组对象

ndarray对象是一个快速而灵活的大数据集容器,可以利用这种数组对整块数据执行一些数学运算,语法和标量元素之间的运算一样。ndarray是一个通用的同构数据多维容器,即:其中的所有元素类型相同。每个数组都有一个shape和一个dtype对象

import numpy as np
# Generate some random data
data = np.random.randn(2, 3) # 产生数据的维度,非负
data
array([[ 0.0929,  0.2817,  0.769 ],
       [ 1.2464,  1.0072, -1.2962]])
# 执行数学运算,作用到元素级别
data + data
array([[ 0.1858,  0.5635,  1.538 ],
       [ 2.4929,  2.0144, -2.5924]])
data * 10
array([[  0.9291,   2.8175,   7.6902],
       [ 12.4643,  10.0719, -12.9622]])
print(data.shape,
data.dtype)
(2, 3) float64

创建ndarray

最简单的方法是使用array函数。它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组

# 从列表创建ndarray
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)
arr1
array([6. , 7.5, 8. , 0. , 1. ])
arr1.dtype
dtype('float64')
# 转换生成一个多维数组
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
arr2
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])
# data2是列表的列表,numpy数组arr2的两个维度的shape是从data2引入的。可以使用ndim属性和shape属性加以验证
print(arr2.ndim,
arr2.shape)
2 (2, 4)
# np.array会尝试为新建的数组推断出一个较为合适的数据类型。数据类型保存在一个特殊的dtype对象中。
print(arr1.dtype,
arr2.dtype)
float64 int32
# zeros和ones分别可以创建指定长度或者形状的全0或者全1的数组。empty可以创建一个没有任何具体值的数组
print(np.zeros(10,),
np.zeros((3, 6)),
np.empty((2, 3, 2)))
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [[0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]] [[[1.0947e-311 2.4703e-322]
  [0.0000e+000 0.0000e+000]
  [0.0000e+000 1.3137e-076]]

 [[5.2737e-091 1.2796e+161]
  [9.9884e-048 9.1533e-071]
  [3.9991e+252 1.4645e-075]]]

np.empty会返回全0的数组的说法是不安全的。很多情况下,他返回的都是一些未初始化的垃圾值

# arange是python内置函数range的数组版
np.arange(15)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
函数说明
array将输入数据(元组,列表,数组或者其他序列类型)转换为ndarray.要么推断出dtype,要么特别指定dtype.默认直接复制输入数据
asarray将输入转换为ndarray,若输入本身就是一个ndarray,就不进行复制
arange类似于内置的range,但返回的是一个ndarray,
ones,ones_like创建全1数组/以另一个数组为参数,根据其形状和dtype创建一个全1数组
zeros,zeros_like类似于ones,ones_like,这里产生的是全0数组
empty,empty_like创建新数组,只分配内存空间但不填充任何值
full, full_like使用fill value中的所有值,根据指定的形状和dtype创建一个数组。full_like使用另一个数组,用相同的形状和dtype
eye, identity创建一个单位阵,方针

ndarray的数据类型

arr1 = np.array([1, 2, 3], dtype=np.float64)
arr2 = np.array([1, 2, 3], dtype=np.int32)
print(arr1.dtype,
arr2.dtype)
float64 int32
# 可以通过ndarray的astype方法明确的将一个数组从一个dtype转换成另一个dtype
arr = np.array([1, 2, 3, 4, 5])
arr.dtype
dtype('int32')
float_arr = arr.astype(np.float64)
float_arr.dtype
dtype('float64')
float_arr
array([1., 2., 3., 4., 5.])
# 将浮点数转换成整数,小数部分将会被截取删除,这里没有进行四舍五入
arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
print(arr)
arr.astype(np.int32)
[ 3.7 -1.2 -2.6  0.5 12.9 10.1]





array([ 3, -1, -2,  0, 12, 10])
# 如果某字符串数组表示的内容全都是数字,也可以使用astype将其转换为数值形式
numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
numeric_strings.astype(float)
array([ 1.25, -9.6 , 42.  ])
numeric_strings.dtype
dtype('S4')

使用np.string_的时候要小心,因为Numpy的字符串数据是大小固定的,发生截取的时候,不会发出警告

int_array = np.arange(10)
calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64)
int_array.astype(calibers.dtype)
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
empty_uint32 = np.empty(8, dtype='u4')
empty_uint32
array([         0, 1075314688,          0, 1075707904,          0,
       1075838976,          0, 1072693248], dtype=uint32)

调用astype总会创建一个新的数组,即使他们之间的dtype相同

numpy数组的运算

矢量化:不用写循环就可以对数据执行批量运算

arr = np.array([[1., 2., 3.], [4., 5., 6.]])
arr
array([[1., 2., 3.],
       [4., 5., 6.]])
print(arr * arr,'\n',
arr - arr)
[[ 1.  4.  9.]
 [16. 25. 36.]] 
 [[0. 0. 0.]
 [0. 0. 0.]]
print(1 / arr,'\n',
arr ** 0.5)
[[1.     0.5    0.3333]
 [0.25   0.2    0.1667]] 
 [[1.     1.4142 1.7321]
 [2.     2.2361 2.4495]]
# 大小相同的数组之间的比较会产生布尔值数组, 大小不同的数组之间的运算叫做广播
arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
print(arr2)
print(arr2 > arr)
[[ 0.  4.  1.]
 [ 7.  2. 12.]]
[[False  True False]
 [ True False  True]]

切片和索引

arr = np.arange(10)
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

与列表不同,数组切片是原始数组的视图,意味着数据不会被复制,因此视图上的任何修改都会直接反映到源数组上

print(arr[5],
arr[5:8])
arr[5:8] = 12
arr
5 [5 6 7]





array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])
arr_slice = arr[5:8]
arr_slice
array([12, 12, 12])
arr_slice[1] = 12345
arr
array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,
           9])
arr_slice[:] = 64
arr
array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
array([7, 8, 9])
print(arr2d[0][2],  # 两种形式是等价的
arr2d[0, 2])
3 3
# 三维数组,
arr3d = np.array([[[1, 2, 3], [4, 5, 6]],
                  [[7, 8, 9], [10, 11, 12]]])
arr3d
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
arr3d.shape
(2, 2, 3)
arr3d[0]
array([[1, 2, 3],
       [4, 5, 6]])
old_values = arr3d[0].copy()
arr3d[0] = 42
arr3d
array([[[42, 42, 42],
        [42, 42, 42]],

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

       [[ 7,  8,  9],
        [10, 11, 12]]])
arr3d[1, 0] # 访问索引以(1, 0)开头的值
array([7, 8, 9])
# 和上面的等价,实际上,先放为第二个(下标1)元素,再访问其中的第一个(下标0)元素
x = arr3d[1]
print(x,
x[0])
[[ 7  8  9]
 [10 11 12]] [7 8 9]
切片索引
print(arr,
arr[1:6])
[ 0  1  2  3  4 64 64 64  8  9] [ 1  2  3  4 64]
print(arr2d,'\n',
arr2d[:2])
[[1 2 3]
 [4 5 6]
 [7 8 9]] 
 [[1 2 3]
 [4 5 6]]
arr2d[:2, 1:]
array([[2, 3],
       [5, 6]])
arr2d[1, :2]
array([4, 5])
arr2d[:2, 2]
array([3, 6])
arr2d[:, :1]
array([[1],
       [4],
       [7]])
arr2d[:2, 1:] = 0
arr2d
array([[1, 0, 0],
       [4, 0, 0],
       [7, 8, 9]])

布尔型索引Boolean Indexing

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7, 4)
print(names,'\n',
data)
['Bob' 'Joe' 'Will' 'Bob' 'Will' 'Joe' 'Joe'] 
 [[-0.6525 -1.2183 -1.3326  1.0746]
 [ 0.7236  0.69    1.0015 -0.5031]
 [-0.6223 -0.9212 -0.7262  0.2229]
 [ 0.0513 -1.1577  0.8167  0.4336]
 [ 1.0107  1.8249 -0.9975  0.8506]
 [-0.1316  0.9124  0.1882  2.1695]
 [-0.1149  2.0037  0.0296  0.7953]]
names == 'Bob'
array([ True, False, False,  True, False, False, False])
# 上述布尔型数组可以用于数组索引
data[names == 'Bob']
array([[-0.6525, -1.2183, -1.3326,  1.0746],
       [ 0.0513, -1.1577,  0.8167,  0.4336]])
print(data[names == 'Bob', 2:],'\n',
data[names == 'Bob', 3])
[[-1.3326  1.0746]
 [ 0.8167  0.4336]] 
 [1.0746 0.4336]
print(names != 'Bob')
data[~(names == 'Bob')]
[False  True  True False  True  True  True]





array([[ 0.7236,  0.69  ,  1.0015, -0.5031],
       [-0.6223, -0.9212, -0.7262,  0.2229],
       [ 1.0107,  1.8249, -0.9975,  0.8506],
       [-0.1316,  0.9124,  0.1882,  2.1695],
       [-0.1149,  2.0037,  0.0296,  0.7953]])
cond = names == 'Bob'
cond
array([ True, False, False,  True, False, False, False])
data[~cond]
array([[ 0.7236,  0.69  ,  1.0015, -0.5031],
       [-0.6223, -0.9212, -0.7262,  0.2229],
       [ 1.0107,  1.8249, -0.9975,  0.8506],
       [-0.1316,  0.9124,  0.1882,  2.1695],
       [-0.1149,  2.0037,  0.0296,  0.7953]])
mask = (names == 'Bob') | (names == 'Will')
mask
array([ True, False,  True,  True,  True, False, False])
data
array([[-0.6525, -1.2183, -1.3326,  1.0746],
       [ 0.7236,  0.69  ,  1.0015, -0.5031],
       [-0.6223, -0.9212, -0.7262,  0.2229],
       [ 0.0513, -1.1577,  0.8167,  0.4336],
       [ 1.0107,  1.8249, -0.9975,  0.8506],
       [-0.1316,  0.9124,  0.1882,  2.1695],
       [-0.1149,  2.0037,  0.0296,  0.7953]])
data[mask]
array([[-0.6525, -1.2183, -1.3326,  1.0746],
       [-0.6223, -0.9212, -0.7262,  0.2229],
       [ 0.0513, -1.1577,  0.8167,  0.4336],
       [ 1.0107,  1.8249, -0.9975,  0.8506]])
data[data < 0] = 0
data
array([[0.    , 0.    , 0.    , 1.0746],
       [0.7236, 0.69  , 1.0015, 0.    ],
       [0.    , 0.    , 0.    , 0.2229],
       [0.0513, 0.    , 0.8167, 0.4336],
       [1.0107, 1.8249, 0.    , 0.8506],
       [0.    , 0.9124, 0.1882, 2.1695],
       [0.    , 2.0037, 0.0296, 0.7953]])
data[names != 'Joe'] = 7
data
array([[7.    , 7.    , 7.    , 7.    ],
       [0.7236, 0.69  , 1.0015, 0.    ],
       [7.    , 7.    , 7.    , 7.    ],
       [7.    , 7.    , 7.    , 7.    ],
       [7.    , 7.    , 7.    , 7.    ],
       [0.    , 0.9124, 0.1882, 2.1695],
       [0.    , 2.0037, 0.0296, 0.7953]])

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

arr = np.empty((8, 4))
for i in range(8):
    arr[i] = i
arr
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.]])
arr[[4, 3, 0, 6]] # 整数数组作为索引
array([[4., 4., 4., 4.],
       [3., 3., 3., 3.],
       [0., 0., 0., 0.],
       [6., 6., 6., 6.]])
arr[[-3, -5, -7]]
array([[5., 5., 5., 5.],
       [3., 3., 3., 3.],
       [1., 1., 1., 1.]])
arr = np.arange(32).reshape((8, 4))
arr
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]])

一次性传入多个数组,返回的是一个一维数组,其中的元素对应各个索引元组

# 一次性传入多个数组,返回的是一个一维数组,其中的元素对应各个索引元组
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
array([ 4, 23, 29, 10])

上面返回的是:(1, 0), (5, 3), (7, 1), (2, 2)

arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]] # 先找出下标为1, 5, 7, 2的行,然后对所有的行,选出0, 3, 1, 2对应的列
array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])

数组转置和轴对换

arr = np.arange(15).reshape((3, 5))
arr
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
arr.T
array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])
arr = np.random.randn(6, 3)
arr
array([[ 0.1181, -0.7485,  0.585 ],
       [ 0.1527, -1.5657, -0.5625],
       [-0.0327, -0.929 , -0.4826],
       [-0.0363,  1.0954,  0.9809],
       [-0.5895,  1.5817, -0.5287],
       [ 0.457 ,  0.93  , -1.5693]])
arr.T
array([[ 0.1181,  0.1527, -0.0327, -0.0363, -0.5895,  0.457 ],
       [-0.7485, -1.5657, -0.929 ,  1.0954,  1.5817,  0.93  ],
       [ 0.585 , -0.5625, -0.4826,  0.9809, -0.5287, -1.5693]])
# 利用np.dot计算矩阵的内积
np.dot(arr.T, arr)
array([[ 0.596 , -0.8442, -0.4421],
       [-0.8442,  8.4411, -0.33  ],
       [-0.4421, -0.33  ,  4.5959]])
arr = np.arange(16).reshape((2, 2, 4))
arr
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])
# 这里第一个轴北换成了第二个,第二个轴被换成了第一个,最后一个轴不变
arr.transpose((1, 0, 2))
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])
arr.T
array([[[ 0,  8],
        [ 4, 12]],

       [[ 1,  9],
        [ 5, 13]],

       [[ 2, 10],
        [ 6, 14]],

       [[ 3, 11],
        [ 7, 15]]])
print(arr,'\n',
arr.swapaxes(1, 2))
[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]] 
 [[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]
arr.swapaxes(0, 1)
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

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

arr = np.arange(10)
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(np.sqrt(arr),'\n',
np.exp(arr))
[0.     1.     1.4142 1.7321 2.     2.2361 2.4495 2.6458 2.8284 3.    ] 
 [   1.        2.7183    7.3891   20.0855   54.5982  148.4132  403.4288
 1096.6332 2980.958  8103.0839]
x = np.random.randn(8)
y = np.random.randn(8)
print(x,
y,
np.maximum(x, y)) # np.maxinum计算了x和y中元素级别最大的元素
[-1.0225 -0.4028  0.2205 -0.1934  0.6692 -1.649  -2.2528 -1.1668] [ 0.3536  0.7021 -0.2746 -0.1391  0.1077 -0.6065 -0.4171 -0.017 ] [ 0.3536  0.7021  0.2205 -0.1391  0.6692 -0.6065 -0.4171 -0.017 ]
arr = np.random.randn(7) * 5
arr
array([-6.1207, -9.0042,  8.1737,  4.945 ,  2.2897,  2.7758,  6.5336])
# modf就是:python内置函数divmod的矢量化版本,他会返回浮点数数组的小数和整数部分
remainder, whole_part = np.modf(arr)
print(remainder,
whole_part)
[-0.1207 -0.0042  0.1737  0.945   0.2897  0.7758  0.5336] [-6. -9.  8.  4.  2.  2.  6.]
print(arr)
np.sqrt(arr)
[-6.1207 -9.0042  8.1737  4.945   2.2897  2.7758  6.5336]





array([   nan,    nan, 2.859 , 2.2237, 1.5132, 1.6661, 2.5561])
# ufuncs接受out选项参数,可以让其再数组的原地进行操作,
print(np.sqrt(arr, arr))
arr
[   nan    nan 2.859  2.2237 1.5132 1.6661 2.5561]





array([   nan,    nan, 2.859 , 2.2237, 1.5132, 1.6661, 2.5561])

利用数组进行数据处理

利用数组表达式代替循环的做法,通常被称为矢量化,矢量化数组运算要比等价的纯python方式快几个数量级

points = np.arange(-5, 5, 0.01) # 1000 equally spaced points
# np.meshgrid函数接受两个一维数组,并产生两个二维矩阵,对应于两个数组中所有的(x, y)对
xs, ys = np.meshgrid(points, points)
ys
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]])
z = np.sqrt(xs ** 2 + ys ** 2)
z
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]])
# 利用matplotlib创建此二维数组的可视化
import matplotlib.pyplot as plt
plt.imshow(z, cmap=plt.cm.gray); plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
Text(0.5, 1.0, 'Image plot of $\\sqrt{x^2 + y^2}$ for a grid of values')

在这里插入图片描述

plt.draw()
<Figure size 720x432 with 0 Axes>
plt.close('all')

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

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])

根据cond中的值选取xarr和yarr的值,当cond中的值为True,选取xarr,否则选取yarr

result = [(x if c else y)
          for x, y, c in zip(xarr, yarr, cond)]
result
[1.1, 2.2, 1.3, 1.4, 2.5]

上述的问题就是:对大数组的处理速度不是很快,且无法用到多维数组之上。可以优化使用为:np.where

mp.where函数是三元表达式 x if condition else y 的矢量化版本

result = np.where(cond, xarr, yarr)
result
array([1.1, 2.2, 1.3, 1.4, 2.5])
arr = np.random.randn(4, 4)
arr
arr > 0
array([[False, False,  True, False],
       [ True,  True, False,  True],
       [False, False, False,  True],
       [ True, False,  True, False]])
arr
array([[-0.4406, -0.3014,  0.4988, -0.824 ],
       [ 1.3206,  0.508 , -0.6534,  0.187 ],
       [-0.3917, -0.2723, -0.0171,  0.6803],
       [ 0.6355, -0.7572,  0.7181, -0.3043]])
# 将所有正值替换为2, 将所有负值替换为-2
np.where(arr > 0, 2, -2)
array([[-2, -2,  2, -2],
       [ 2,  2, -2,  2],
       [-2, -2, -2,  2],
       [ 2, -2,  2, -2]])
# 仅仅替换其中的正值
np.where(arr > 0, 2, arr) # set only positive values to 2
array([[-0.4406, -0.3014,  2.    , -0.824 ],
       [ 2.    ,  2.    , -0.6534,  2.    ],
       [-0.3917, -0.2723, -0.0171,  2.    ],
       [ 2.    , -0.7572,  2.    , -0.3043]])

数学和统计方法

arr = np.random.randn(5, 4)
arr
array([[-1.6778,  0.427 , -1.5637, -0.3675],
       [ 1.0459,  1.22  , -0.2477, -0.4162],
       [-0.1167, -1.8448,  2.0687, -0.777 ],
       [ 1.4402, -0.1106,  1.2274,  1.9208],
       [ 0.7464,  2.2247, -0.6794,  0.7274]])
print(arr.mean(),'\n',
np.mean(arr),'\n',
arr.sum())
0.2623475822569136 
 0.2623475822569136 
 5.246951645138273
arr.mean(axis=1) # 行的均值
# arr.sum(axis=0) # 列的均值
array([-0.7955,  0.4005, -0.1674,  1.1194,  0.7548])
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
arr.cumsum()
array([ 0,  1,  3,  6, 10, 15, 21, 28], dtype=int32)

其他如cumsum和cumprod之类的⽅法则不聚合,⽽是产⽣⼀个
由中间结果组成的数组:

arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr
# arr.cumsum(axis=0)
#  arr.cumprod(axis=1)
array([[ 0,  1,  2],
       [ 3,  5,  7],
       [ 9, 12, 15]], dtype=int32)

用于布尔型数组的方法

arr = np.random.randn(100)
(arr > 0).sum() # Number of positive values
40

any用于统计数组中是否存在一个或者多个True,而all则检查数组中所有的值是否都是True

bools = np.array([False, False, True, False])
bools.any()
bools.all()
False

排序

arr = np.random.randn(6)
arr
arr.sort()
arr
arr = np.random.randn(5, 3)
arr
arr.sort(1)
arr
large_arr = np.random.randn(1000)
large_arr.sort()
large_arr[int(0.05 * len(large_arr))] # 5% quantile

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

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
np.unique(names)
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
np.unique(ints)
sorted(set(names))
values = np.array([6, 0, 0, 3, 2, 5, 6])
np.in1d(values, [2, 3, 6])

用于数组的文件输入输出

arr = np.arange(10)
np.save('some_array', arr)
np.load('some_array.npy')
np.savez('array_archive.npz', a=arr, b=arr)
arch = np.load('array_archive.npz')
arch['b']
np.savez_compressed('arrays_compressed.npz', a=arr, b=arr)
!rm some_array.npy
!rm array_archive.npz
!rm arrays_compressed.npz

线性代数

x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
x
y
x.dot(y)
np.dot(x, y)
np.dot(x, np.ones(3))
x @ np.ones(3)
from numpy.linalg import inv, qr
X = np.random.randn(5, 5)
mat = X.T.dot(X)
inv(mat)
mat.dot(inv(mat))
q, r = qr(mat)
r

伪随机数生成

samples = np.random.normal(size=(4, 4))
samples
from random import normalvariate
N = 1000000
%timeit samples = [normalvariate(0, 1) for _ in range(N)]
%timeit np.random.normal(size=N)
np.random.seed(1234)
rng = np.random.RandomState(1234)
rng.randn(10)

随机漫步

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)
plt.figure()
plt.plot(walk[:100])
np.random.seed(12345)
nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum()
walk.min()
walk.max()
(np.abs(walk) >= 10).argmax()

一次模拟多个随机漫步

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
walks.max()
walks.min()
hits30 = (np.abs(walks) >= 30).any(1)
hits30
hits30.sum() # Number that hit 30 or -30
crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1)
crossing_times.mean()
steps = np.random.normal(loc=0, scale=0.25,
                         size=(nwalks, nsteps))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值