Python Numpy 入门

import numpy as np

Arrays/数组

看你数组的维度啦,我自己的话比较简单粗暴,一般直接把1维数组就看做向量/vector,2维数组看做2维矩阵,3维数组看做3维矩阵…

可以调用np.array去从list初始化一个数组:

a = np.array([1, 2, 3])
print(a)
[1 2 3]
print(type(a))
<class 'numpy.ndarray'>
type([1,2,3])
list
a[2]
3
a[0] = 5
print(a)
[5 2 3]
b = np.array([[1,2,3], [2,3,4]])
print(b)
[[1 2 3]
 [2 3 4]]
print(type(b))
<class 'numpy.ndarray'>
print(b.shape)
(2, 3)
print(b[0,2])
3

ndarray = n dimensional array

有一些内置的创建数组的函数:

a = np.zeros((2,3))
print(a)
[[ 0.  0.  0.]
 [ 0.  0.  0.]]
b = np.ones((1,2))
print(b)
[[ 1.  1.]]
c = np.full((2,2), 8)
print(c)
[[8 8]
 [8 8]]
d = np.eye(3) #对角矩阵
print(d)
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]
e = np.random.random((3,2)) #生成[0,1)的实数矩阵
print(e)
[[ 0.34222445  0.254503  ]
 [ 0.07192044  0.39303621]
 [ 0.64905403  0.77977616]]
f = np.empty((2,3,4))
print(f)
[[[  8.09661985e-312   7.21335843e-322   0.00000000e+000   0.00000000e+000]
  [  1.29061414e-306   1.16095484e-028   5.28595592e-085   1.01445441e+242]
  [  2.93623251e-062   1.75300433e+243   4.25136003e-096   1.04716878e-142]]

 [[  4.54813897e-144   5.83001600e+199   7.48468178e+251   5.04621362e+180]
  [  7.49779533e+247   3.88625532e+285   2.02647441e+267   1.16317829e-028]
  [  8.76739488e+252   1.14011198e+243   5.54175224e+257   8.34402698e-308]]]
print(f.shape)
(2, 3, 4)
g = np.arange(15)  #类似python的range()
print(g)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]
print(g.shape)
(15,)
type((2,3))
tuple

数组可以有不同的数据类型

arr = np.array([1,2,3])
print(arr.dtype) #元素数据类型
int32
arr = np.array([1,2,3], dtype=np.float64)
print(arr.dtype)
print(arr)
arr
float64
[1. 2. 3.]





array([1., 2., 3.])
arr
array([ 1.,  2.,  3.])
arr = np.array([1,2,3], dtype=np.int64)
print(arr.dtype)
int64

生成数组时可以指定数据类型,如果不指定numpy会自动匹配合适的类型

使用astype复制数组并转换元素数据类型

int_arr = np.array([1,2,3,4,5])
print(int_arr, int_arr.dtype)
[1 2 3 4 5] int32
float_arr = int_arr.astype(np.float64) #使用astype复制数组并转换元素数据类型
print(float_arr.dtype, float_arr)
float64 [ 1.  2.  3.  4.  5.]

使用astype将float转换为int时小数部分被舍弃

float_arr = np.array([3.5,2.3,4.8,-2.2])
print(float_arr)
[ 3.5  2.3  4.8 -2.2]
int_arr = float_arr.astype(np.int64) #使用astype将float转换为int时小数部分被舍弃
print(int_arr, int_arr.dtype)   #int64比int32能表示更大范围的数字
[ 3  2  4 -2] int64

使用astype把字符串转换为数组,如果失败抛出异常。

str_arr = np.array(['1.24', '2.2', '5.8','sads'], dtype=np.string_)
str_arr
array([b'1.24', b'2.2', b'5.8'], dtype='|S4')
float_arr = str_arr.astype(np.float) #float_arr = str_arr.astype(np.float)
print(float_arr)
[1.24 2.2  5.8 ]

astype使用其它数组的数据类型作为参数

int_arr = np.arange(10)
float_arr = np.array([2.3 ,4.6 ,9.8])
print(float_arr.dtype, int_arr.dtype)
float64 int32
int_arr.astype(dtype=float_arr.dtype)
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])

Array indexing/数组取值和赋值

Numpy提供了蛮多种取值的方式的.

a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
print(a)
print(a.shape)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
(3, 4)

可以像list一样切片(多维数组可以从各个维度同时切片):

b = a[0:2,2:4]   #b = a[0:2,2:4].copy()再修改b,a不会变
print(b)
print(a)
[[3 4]
 [7 8]]
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

虽然,怎么说呢,不建议你这样去赋值,但是你确实可以修改切片出来的对象,然后完成对原数组的赋值.

b[0,0] = 111111
print(b)
print(a)   #修改了a切片的b,a也变了
[[111111      4]
 [     7      8]]
[[     1      2 111111      4]
 [     5      6      7      8]
 [     9     10     11     12]]

创建3x4的2维数组/矩阵

a
array([[     1,      2, 111111,      4],
       [     5,      6,      7,      8],
       [     9,     10,     11,     12]])

你就放心大胆地去取你想要的数咯:

row_r1 = a[1,:]   
print(row_r1, row_r1.shape)
[5 6 7 8] (4,)
row_r2 = a[1:2, :]   #切片操作
print(row_r2, row_r2.shape)
[[5 6 7 8]] (1, 4)
row_r3 = a[[1], :]   #索引操作和切片混用
print(row_r3, row_r3.shape)
[[5 6 7 8]] (1, 4)

试试在第2个维度上切片也一样的:

a
array([[     1,      2, 111111,      4],
       [     5,      6,      7,      8],
       [     9,     10,     11,     12]])
col_r1 = a[:, 1]
print(col_r1, col_r1.shape)
[ 2  6 10] (3,)
col_r2 = a[:, 1:2]
print(col_r2, col_r2.shape)
[[ 2]
 [ 6]
 [10]] (3, 1)

下面这个高级了,更自由地取值和组合,但是要看清楚一点:

a = np.array([[1,2], [3, 4], [5, 6]])
print(a)
[[1 2]
 [3 4]
 [5 6]]
print(a[[0,1,2], [0,1,0]])  #(0,0)(1,1)(2,0)
print(a[[0,1,2], [0,1,0]].shape)
[1 4 5]
(3,)
print(np.array( [a[0,0], a[1,1], a[2,0]] ))
[1 4 5]
print(a)
print(a[[0,0], [1,0]])   #(0,1)(0,0))
print(np.array([a[0,0], a[0,1]]))
[[1 2]
 [3 4]
 [5 6]]
[2 1]
[1 2]

再来熟悉一下

先创建一个2维数组


a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

用下标生成一个向量

b = np.array([0, 2,0,1])

你能看明白下面做的事情吗?

a[np.arange(4), b]
array([ 1,  6,  7, 11])

既然可以取出来,我们当然也可以对这些元素操作咯

a[np.arange(4), b] += 10
print(a)
[[11  2  3]
 [ 4  5 16]
 [17  8  9]
 [10 21 12]]

比较fashion的取法之一,用条件判定去取(但是很好用):

a = np.array([[1,2], [3, 4], [5, 6]])
print(a)
[[1 2]
 [3 4]
 [5 6]]
bool_index = (a > 2)
print(bool_index)
[[False False]
 [ True  True]
 [ True  True]]

用刚才的布尔型数组作为下标就可以去除符合条件的元素啦

print(a[bool_index].shape)
a[bool_index]
(4,)





array([3, 4, 5, 6])

其实一句话也可以完成是不是?

print(a[a>2])
[3 4 5 6]

那个,真的,其实还有很多细节,其他的方式去取值,你可以看看官方文档。

我们一起来来总结一下,看下面切片取值方式(对应颜色是取出来的结果):

注意:逗号分隔维度,比如:行、列

  • 切片操作
  • 索引操作

Datatypes

我们可以用dtype来看numpy数组中元素的类型:

x = np.array([1, 2])  # numpy构建数组的时候自己会确定类型
y = np.array([1.0, 2.0])
z = np.array([1, 2], dtype=np.int64)
print(x.dtype, y.dtype, z.dtype)
int32 float64 int64

更多的内容可以读读文档.

数学运算

下面这些运算才是你在科学运算中经常经常会用到的,比如逐个元素的运算如下:


x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)
print(x)
print(y)
[[1. 2.]
 [3. 4.]]
[[5. 6.]
 [7. 8.]]
print(x.shape)
print(y.shape)
(2, 2)
(2, 2)

逐元素求和有下面2种方式

x+y
array([[ 6.,  8.],
       [10., 12.]])
np.add(x,y)
array([[ 6.,  8.],
       [10., 12.]])

逐元素作差

x-y
array([[-4., -4.],
       [-4., -4.]])
np.subtract(x,y)
array([[-4., -4.],
       [-4., -4.]])

逐元素相乘

x*y
array([[ 5., 12.],
       [21., 32.]])
np.multiply(x,y)
array([[ 5., 12.],
       [21., 32.]])

逐元素相除

x/y
array([[0.2       , 0.33333333],
       [0.42857143, 0.5       ]])
np.divide(x, y)
array([[0.2       , 0.33333333],
       [0.42857143, 0.5       ]])

逐元素求平方根!!!

np.sqrt(x)    #开方
array([[ 1.        ,  1.41421356],
       [ 1.73205081,  2.        ]])

那如果我要做矩阵的乘法运算怎么办!!!恩,别着急,照着下面写就可以了:

matrix multiplication

v = np.array([9,10])
w = np.array([10,11])
print(v.shape)
(2,)

求向量内积

v.dot(w)
200
np.dot(v,w)
200

矩阵的乘法 dot()

x = np.array([[1,2], [3,4]])
y = np.array([[5,6], [7,8]])
print(x)
print()
print(y)
[[1 2]
 [3 4]]

[[5 6]
 [7 8]]
v
array([ 9, 10])
print(x.dot(v))
[29 67]
np.dot(x, v)
array([29, 67])
x.dot(y)
array([[19, 22],
       [43, 50]])
np.dot(x,y)
array([[19, 22],
       [43, 50]])

转置和数学公式一样,简单粗暴

x
array([[1, 2],
       [3, 4]])
x.T
array([[1, 3],
       [2, 4]])

需要说明一下,1维的vector转置还是自己

v.shape
(2,)
v.T.shape
(2,)

2维的就不一样了

w = np.array([[1,2,3]])
print(w, w.shape)
[[1 2 3]] (1, 3)
print(w.T)
print(w.T.shape)
[[1]
 [2]
 [3]]
(3, 1)

利用转置矩阵做dot product

# numpy.random.randn(d0, d1, …, dn维)是从标准正态分布中返回一个或多个样本值。
# numpy.random.rand(d0, d1, …, dn)是随机样本位于[0, 1)中。 
arr = np.random.randn(6,3)
arr
array([[-0.85184372,  1.37181588, -0.21604062],
       [ 0.41340894, -0.1304486 , -1.50058753],
       [ 0.23102015,  0.3708004 , -1.6123044 ],
       [-0.57450372,  0.28874061,  1.76457975],
       [ 0.30296641,  1.02667051, -0.25804175],
       [ 0.9156399 ,  0.61960007, -1.04064778]])
print(arr.T.dot(arr))
[[ 2.55200533  1.76128844  0.87175679]
 [ 1.76128844  4.29867937 -1.10222404]
 [ 0.87175679 -1.10222404  1.42099216]]
print(np.dot(arr,arr))
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-158-8f8e98f47ed1> in <module>()
----> 1 print(np.dot(arr,arr))


ValueError: shapes (6,3) and (6,3) not aligned: 3 (dim 1) != 6 (dim 0)

高维的tensor也可以做转置(一维叫vector,二维叫matrix,三位以上就叫tensor)

arr = np.arange(16).reshape(2,2,4)
print(arr, arr.shape)
[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]] (2, 2, 4)
print(arr.transpose((1,0,2))) #维度转置,传的tuple
[[[ 0  1  2  3]
  [ 8  9 10 11]]

 [[ 4  5  6  7]
  [12 13 14 15]]]
print(arr.transpose((0,2,1)))
[[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]
print(arr.transpose((2,1,0)))
[[[ 0  8]
  [ 4 12]]

 [[ 1  9]
  [ 5 13]]

 [[ 2 10]
  [ 6 14]]

 [[ 3 11]
  [ 7 15]]]
print(arr.swapaxes(1,2)) #把第一维度和第二维度交换,同arr.transpose((0,2,1))
[[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]
x = np.arange(24).reshape(2,3,4)
y = np.arange(8).reshape(4,2)
print(x)
print()
print(y)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

[[0 1]
 [2 3]
 [4 5]
 [6 7]]
print(np.matmul(x,y).shape)  #矩阵乘法
(2, 3, 2)
print(np.dot(x,y).shape)
(2, 3, 2)
x = np.arange(24).reshape(2,3,4)
y = np.arange(16).reshape(2,4,2)
print(np.dot(x,y).shape)
(2, 3, 2, 2)
np.matmul(x,y).shape
(2, 3, 2)

你猜你做科学运算会最常用到的矩阵内元素的运算是什么?对啦,是求和,用 sum可以完成:

x= np.array([[1,2], [3,4]])
print(x)
[[1 2]
 [3 4]]
print(np.sum(x))
print(x.sum())
10
10
print(np.sum(x, axis=0))  #第0维求和(按行)
[4 6]
print(np.sum(x, axis=1))
[3 7]
print(np.mean(x))   #求平均
print(np.mean(x, axis=0))
print(np.mean(x, axis=1))
2.5
[2. 3.]
[1.5 3.5]

还有一些其他我们可以想到的运算,比如求和,求平均,求cumulative sum(累加求和),sumulative product用numpy都可以做到

print(x)
print()
print(x.cumsum(axis=0))
print()
print(x.cumsum(axis=1))
[[1 2]
 [3 4]]

[[1 2]
 [4 6]]

[[1 3]
 [3 7]]
print(x.cumprod(axis=0))
print()
print(x.cumprod(axis=1))
[[1 2]
 [3 8]]

[[ 1  2]
 [ 3 12]]

我想说最基本的运算就是上面这个样子,更多的运算可能得查查文档.

其实除掉基本运算,我们经常还需要做一些操作,比如矩阵的变形,转置和重排等等:

一维数组的排序

arr = np.random.randn(8) * 10
print(arr)
[-15.78997677 -12.10676988   0.51148087  -9.8265767    4.83704543
  -2.74087509  11.02576343   3.51866316]
arr.sort()
print(arr)
[-15.78997677 -12.10676988  -9.8265767   -2.74087509   0.51148087
   3.51866316   4.83704543  11.02576343]

二维数组也可以在某些维度上排序

arr = np.random.randn(5,3) * 10
print(arr)
[[ -1.64638996  -1.2114224    2.15896971]
 [  6.00536939  -7.71788794   6.54291646]
 [  2.30925965   4.72675272  -0.2759866 ]
 [  2.92760387 -11.45580554  -7.84082136]
 [ -5.01085861  -0.96178148  -5.77203831]]
arr.sort(1)  #对第一维排序,按列排序
print(arr)
[[-0.85184372 -0.21604062  1.37181588]
 [-1.50058753 -0.1304486   0.41340894]
 [-1.6123044   0.23102015  0.3708004 ]
 [-0.57450372  0.28874061  1.76457975]
 [-0.25804175  0.30296641  1.02667051]
 [-1.04064778  0.61960007  0.9156399 ]]

下面我们做一个小案例,找出排序后位置在5%的数字

large_arr = np.random.randn(100)
large_arr.sort()
print(large_arr)
print(large_arr[int(0.05 * len(large_arr))])
[-3.32772536 -2.38357921 -1.91101139 -1.82796108 -1.63074559 -1.5184678
 -1.36493474 -1.30583617 -1.23538116 -1.15560689 -1.08581495 -1.07939886
 -0.95936475 -0.91620548 -0.91088622 -0.87016602 -0.86783402 -0.86021967
 -0.83809007 -0.81316694 -0.771235   -0.75507747 -0.73936096 -0.71342388
 -0.7122469  -0.68227728 -0.67348156 -0.66165921 -0.64434037 -0.63927408
 -0.6272252  -0.57524841 -0.5452093  -0.51929193 -0.51785612 -0.49343037
 -0.46699192 -0.4227325  -0.36615112 -0.36134966 -0.32261952 -0.31611974
 -0.30127439 -0.27337334 -0.23123255 -0.22029143 -0.21980615 -0.20945839
 -0.19774684 -0.19529999 -0.18987202 -0.17615543 -0.17611459 -0.13758887
 -0.13605848 -0.1134112  -0.11107712 -0.10567309 -0.09276111 -0.07829745
 -0.06368005  0.06528584  0.07527503  0.12409513  0.1257661   0.13276165
  0.14650325  0.17683267  0.19879493  0.20977401  0.2144876   0.21727443
  0.22817286  0.2331437   0.31541574  0.35387287  0.36970086  0.37454062
  0.4114625   0.44772773  0.45544221  0.47862329  0.56289282  0.57336266
  0.5789837   0.85722037  0.87945755  1.01064522  1.03277142  1.05928647
  1.05951479  1.22103753  1.22575475  1.23585555  1.37049702  1.37374003
  1.53620931  1.53714294  1.60858385  2.12032196]
-1.5184677952073133

Broadcasting广播

作用是什么呢,我们设想一个场景,如果要用小的矩阵去和大的矩阵做一些操作,但是希望小矩阵能循环和大矩阵的那些块做一样的操作,那急需要Broadcasting啦

我们要做一件事情,给x的每一行都逐元素加上一个向量,然后生成y

x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
print(x)
print()
print(v)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

[1 0 1]
y = np.empty_like(x) #清0一个矩阵
print(y)
[[0 0 0]
 [0 0 0]
 [0 0 0]
 [0 0 0]]

比较粗暴的方式是,用for循环逐个相加

for i in range(4):
    y[i,:] = x[i,:] + v

print(y)
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]

这种方法当然可以啦,问题是不高效嘛,如果你的x矩阵行数非常多,那就很慢的咯:

Numpy broadcasting allows us to perform this computation without actually creating multiple copies of v. Consider this version, using broadcasting:

因为broadcasting的存在,你上面的操作可以简单地汇总成一个求和操作

print(x.shape, v.shape)
x + v
(4, 3) (3,)





array([[ 2,  2,  4],
       [ 5,  5,  7],
       [ 8,  8, 10],
       [11, 11, 13]])

当操作两个array时,numpy会逐个比较它们的shape,在下述情况下,两arrays会兼容和输出broadcasting结果:

  1. 相等
  2. 其中一个为1,(进而可进行拷贝拓展已至,shape匹配)

比如求和的时候有:

Image (3d array):  256 x 256 x 3
Scale (1d array):              3
Result (3d array): 256 x 256 x 3

A      (4d array):  8 x 1 x 6 x 1
B      (3d array):      7 x 1 x 5
Result (4d array):  8 x 7 x 6 x 5

A      (2d array):  5 x 4
B      (1d array):      1
Result (2d array):  5 x 4

A      (2d array):  15 x 3 x 5
B      (1d array):  15 x 1 x 5
Result (2d array):  15 x 3 x 5

下面是一些 broadcasting 的例子:

我们来理解一下broadcasting的这种用法

先把v变形成3x1的数组/矩阵,然后就可以broadcasting加在w上了:

v = np.array([1,2,3])
w = np.array([4,5])
print(v.shape, w.shape)        
(3,) (2,)
v = v.reshape(3,1)
print(v.shape)
(3, 1)

(3,1) 和 (1,2)维度为1的复制,变成(3,2)

v + w    
array([[5, 6],
       [6, 7],
       [7, 8]])

那如果要把一个矩阵的每一行都加上一个向量呢

x = np.array([[1,2,3], [4,5,6]])  
v = np.array([1,2,3])
print(x + v)   #(2,3)和(1,3)复制变成(2,3)
[[2 4 6]
 [5 7 9]]

x = np.array([[1,2,3], [4,5,6]]) # 2x3的
w = np.array([4,5]) # 2
(x.T + w).T
array([[ 5,  6,  7],
       [ 9, 10, 11]])

上面那个操作太复杂了,其实我们可以直接这么做嘛

x + np.reshape(w, (2,1)) #先把w转成列向量
array([[ 5,  6,  7],
       [ 9, 10, 11]])

broadcasting当然可以逐元素运算了

总结一下broadcasting,可以看看下面的图:

矩阵哪个维度为1,按另一个对应的维度扩充(复制)

逻辑运算


x_arr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
y_arr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
print(np.where(cond, x_arr, y_arr))  #where(bool,x,y) True拿x_arr,False拿y_arr
[1.1 2.2 1.3 1.4 2.5]
arr = np.random.randn(4,4)
print(arr)
[[ 0.94534017  0.04955986  0.20184702  0.40272432]
 [-0.20872753 -0.04952711  0.0059752  -1.9356753 ]
 [ 1.20042485 -0.92834374  1.57810979 -0.96378859]
 [-2.09492281 -0.38678213 -0.67656147  1.45629059]]
arr > 0
array([[ True,  True,  True,  True],
       [False, False,  True, False],
       [ True, False,  True, False],
       [False, False, False,  True]], dtype=bool)
print(np.where(arr > 0, 1,-1))
[[ 1  1  1  1]
 [-1 -1  1 -1]
 [ 1 -1  1 -1]
 [-1 -1 -1  1]]
print(np.where(arr > 0, 1,arr))
[[ 1.          1.          1.          1.        ]
 [-0.20872753 -0.04952711  1.         -1.9356753 ]
 [ 1.         -0.92834374  1.         -0.96378859]
 [-2.09492281 -0.38678213 -0.67656147  1.        ]]

一些更高级的ndarray处理

使用reshape来改变tensor的形状

numpy可以很容易地把一维数组转成二维数组,三维数组。

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

       [[4, 5],
        [6, 7]]])
arr = np.arange(15)
print(arr.reshape(5,3).shape)
(5, 3)

如果我们在某一个维度上写上-1,numpy会帮我们自动推导出正确的维度

print(arr.reshape(5,-1).shape)
(5, 3)

还可以从其他的ndarray中获取shape信息然后reshape

other_arr = np.ones((3,5))
print(other_arr.shape) # tuple
(3, 5)
arr.reshape(other_arr.shape)
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

高维数组可以用ravel来拉平

arr = arr.reshape(other_arr.shape)
print(arr)
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
arr.ravel().shape
(15,)

连接两个二维数组

arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
print(arr1, "\n\n", arr2)
[[1 2 3]
 [4 5 6]] 

 [[ 7  8  9]
 [10 11 12]]
np.concatenate([arr1, arr2], axis=0)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])
np.concatenate([arr1, arr2], axis=1)
array([[ 1,  2,  3,  7,  8,  9],
       [ 4,  5,  6, 10, 11, 12]])

所谓堆叠,参考叠盘子。。。连接的另一种表述
垂直stack与水平stack

np.vstack((arr1, arr2)) # vertical垂直的   #注意:传入tuple
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])
np.hstack((arr1, arr2)) # horizontal水平的
array([[ 1,  2,  3,  7,  8,  9],
       [ 4,  5,  6, 10, 11, 12]])

拆分数组

arr = np.random.rand(5,5)
print(arr)
[[ 0.80642843  0.43253953  0.24511404  0.21328645  0.50991311]
 [ 0.19373378  0.72169396  0.05192132  0.1746048   0.69771988]
 [ 0.59689743  0.82253158  0.03346062  0.9002945   0.03960687]
 [ 0.06061257  0.27390675  0.19740262  0.76815388  0.02035703]
 [ 0.58031701  0.63341072  0.75286027  0.82066801  0.24301514]]
first, second, third = np.split(arr, [1,3], axis=0)
print(first, '\n\n', second, '\n\n', third)
[[ 0.80642843  0.43253953  0.24511404  0.21328645  0.50991311]] 

 [[ 0.19373378  0.72169396  0.05192132  0.1746048   0.69771988]
 [ 0.59689743  0.82253158  0.03346062  0.9002945   0.03960687]] 

 [[ 0.06061257  0.27390675  0.19740262  0.76815388  0.02035703]
 [ 0.58031701  0.63341072  0.75286027  0.82066801  0.24301514]]

堆叠辅助

arr = np.arange(6)
arr1 = arr.reshape((3, 2))
arr2 = np.random.randn(3, 2)
print(arr1)
print(arr2)
[[0 1]
 [2 3]
 [4 5]]
[[ 1.1975479   0.16594726]
 [ 0.36205334 -0.39277953]
 [-0.16262638  0.98295117]]

r_用于按行堆叠row

print(np.r_[arr1, arr2])
print()
[[ 0.          1.        ]
 [ 2.          3.        ]
 [ 4.          5.        ]
 [ 1.1975479   0.16594726]
 [ 0.36205334 -0.39277953]
 [-0.16262638  0.98295117]]

c_用于按列堆叠column

print(np.c_[np.r_[arr1, arr2], arr])
print()
[[ 0.          1.          0.        ]
 [ 2.          3.          1.        ]
 [ 4.          5.          2.        ]
 [-0.60392123 -0.1769936   3.        ]
 [ 0.46523138  0.71963034  4.        ]
 [-0.51733042  1.50108329  5.        ]]

切片直接转为数组

np.c_[1:6, -5:0,2:7]
array([[ 1, -5,  2],
       [ 2, -4,  3],
       [ 3, -3,  4],
       [ 4, -2,  5],
       [ 5, -1,  6]])

使用repeat来重复

按元素重复

arr = np.arange(3)
print(arr)
print(arr.repeat(3)) #把没个元素重复3次
[0 0 0 1 1 1 2 2 2]
print(arr.repeat([2,3,5]))  #指定元素重复次数
[0 0 1 1 1 2 2 2 2 2]

指定axis来重复

arr = np.random.rand(2,2)
print(arr)
[[ 0.9682022   0.99265567]
 [ 0.62174828  0.12614083]]
print(arr.repeat(2, axis=0))
[[ 0.90063544  0.36862431  0.46734451]
 [ 0.90063544  0.36862431  0.46734451]
 [ 0.61467785  0.63962631  0.61288228]
 [ 0.61467785  0.63962631  0.61288228]]
print(arr.repeat(2, axis=1))
[[ 0.90063544  0.90063544  0.36862431  0.36862431  0.46734451  0.46734451]
 [ 0.61467785  0.61467785  0.63962631  0.63962631  0.61288228  0.61288228]]

Tile: 参考贴瓷砖
numpy tile

print(arr)
print()
print(np.tile(arr, 2))  #整块重复
[[ 0.9682022   0.99265567]
 [ 0.62174828  0.12614083]]

[[ 0.9682022   0.99265567  0.9682022   0.99265567]
 [ 0.62174828  0.12614083  0.62174828  0.12614083]]
print(np.tile(arr, (2,3)))   #整块当成一个block,重复成一个2行3列
[[ 0.9682022   0.99265567  0.9682022   0.99265567  0.9682022   0.99265567]
 [ 0.62174828  0.12614083  0.62174828  0.12614083  0.62174828  0.12614083]
 [ 0.9682022   0.99265567  0.9682022   0.99265567  0.9682022   0.99265567]
 [ 0.62174828  0.12614083  0.62174828  0.12614083  0.62174828  0.12614083]]

numpy的文件输入输出

读取csv文件作为数组

arr = np.loadtxt('array_ex.txt', delimiter=',') #分隔符是“,”
print(arr)
[[ 0.580052  0.18673   1.040717  1.134411]
 [ 0.194163 -0.636917 -0.938659  0.124094]
 [-0.12641   0.268607 -0.695724  0.047428]
 [-1.484413  0.004176 -0.744203  0.005487]
 [ 2.302869  0.200131  1.670238 -1.88109 ]
 [-0.19323   1.047233  0.482803  0.960334]]

数组文件读写

arr = np.arange(50).reshape(2,5,5)
print(arr)
[[[ 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 32 33 34]
  [35 36 37 38 39]
  [40 41 42 43 44]
  [45 46 47 48 49]]]
np.save('some_array', arr)
arr2 = np.load('some_array.npy')
print(arr2)
[[[ 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 32 33 34]
  [35 36 37 38 39]
  [40 41 42 43 44]
  [45 46 47 48 49]]]

多个数组可以一起压缩存储

arr3 = np.arange(15).reshape(3,5)
np.savez("array_archive.npz", arr=arr, b=arr2, c=arr3)
arch = np.load('array_archive.npz')
#相当于读字典
print(arch['arr'])
[[[ 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 32 33 34]
  [35 36 37 38 39]
  [40 41 42 43 44]
  [45 46 47 48 49]]]
arch['b']
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, 32, 33, 34],
        [35, 36, 37, 38, 39],
        [40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49]]])
arch['c']
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

猜你喜欢

转载自blog.csdn.net/douhh_sisy/article/details/80557029