Python中数组(numpy.array)的基本操作

一、为什么要用numpy

Python中提供了list容器,可以当作数组使用。但列表中的元素可以是任何对象,因此列表中保存的是对象的指针,这样一来,为了保存一个简单的列表[1,2,3]。就需要三个指针和三个整数对象。对于数值运算来说,这种结构显然不够高效。
Python虽然也提供了array模块,但其只支持一维数组,不支持多维数组(在TensorFlow里面偏向于矩阵理解),也没有各种运算函数。因而不适合数值运算。NumPy的出现弥补了这些不足。

(——摘自张若愚的《Python科学计算》)

import numpy as np

二、常规创建方法

1.普通创建:np.array()
a = np.array([2,3,4])
b = np.array([2.0,3.0,4.0])
c = np.array([[1.0,2.0],[3.0,4.0]])
d = np.array([[1,2],[3,4]],dtype=complex) # 指定数据类型
print(a, a.dtype, '\n')
print(b, b.dtype, '\n')
print(c, c.dtype, '\n')
print(d, d.dtype, '\n')

结果:
[2 3 4] int32 

[2. 3. 4.] float64 

[[1. 2.]
 [3. 4.]] float64 

[[1.+0.j 2.+0.j]
 [3.+0.j 4.+0.j]] complex128 

2.常用创建特殊array的函数
(1)创建等差数列(指定范围和等差):np.arange()
# 0为起点,间隔为1时可缺省(引起歧义下不可缺省)
# 左闭右开
print(np.arange(0,7,1,dtype=np.int16))
print(np.arange(1,7,2,dtype=np.int16))

结果:
[0 1 2 3 4 5 6]
[1 3 5]
(2)创建等差数列(指定元素个数):np.linspace()
# 起点为-1,终点为2,取5个点
print(np.linspace(-1,2,5))
print(np.linspace(1,7,2))

结果:
[-1.   -0.25  0.5   1.25  2.  ]
[1. 7.]
(3)创建全1张量:np.ones()
# 2页,3行,4列,全1,指定数据类型
print(np.ones((2,3,4),dtype=np.int16))

结果:
[[[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]

 [[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]]
(4)创建全0张量:np.zeros()
# 2页,3行,4列,全0
print(np.zeros((2,3,4)))

结果:
[[[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]

 [[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]]
(5)创建空张量:np.empty()
# 值取决于内存
print(np.empty((2,3)))

结果:
[[1.39069238e-309 1.39069238e-309 1.39069238e-309]
 [1.39069238e-309 1.39069238e-309 1.39069238e-309]]
(6)创建随机数:np.random
import numpy as np

# rand                 Uniformly distributed values.
# randn                Normally distributed values.
# ranf                 Uniformly distributed floating point numbers.
# random_integers      Uniformly distributed integers in a given range.
#                      (deprecated, use ``integers(..., closed=True)`` instead)
# random_sample        Alias for `random_sample`
# randint              Uniformly distributed integers in a given range
# seed                 Seed the legacy random number generator.

# 0-1 均匀分布,指定各个维度
print(np.random.rand(2,3), '\n')
# 正态分布,指定各个维度
print(np.random.randn(2,3), '\n')
# 产生单个浮点数,无参
print(np.random.ranf(), '\n')
# 0-3 均匀分布的整数
print(np.random.randint(0,3,(2,3)), '\n')


结果:
[[0.37756033 0.80360956 0.63485679]
 [0.14394863 0.78606939 0.52234344]]

[[ 0.18956566  0.05175242  0.0484264 ]
 [ 1.00672726 -1.22815671 -0.25344504]]

0.18570151339690422

[[1 2 1]
 [2 1 1]]

三、array变换

1.类型转换
print(float(1))
print(int(1.0))
print(bool(2))
print(float(True))

结果:
1.0
1
True
1.0
2.形状变换

从左到右,从上向下
一维数组打印成行,二维数组打印成矩阵,三维数组打印成矩阵列表

print(np.arange(12).reshape(3,4), '\n') # 可以改变输出形状
print(np.arange(24).reshape(2,3,4)) # 2页,3行,4页

结果:  
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
 
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

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

四、运算

1.元素级基本运算

测试数据:

a = np.arange(4)
b = np.array([1,2,3,4])

结果:
[0 1 2 3] [1 2 3 4]
(1)array间的运算为对应元素运算:
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a**b)

结果:
[1 3 5 7]
[-1 -1 -1 -1]
[ 0  2  6 12]
[0.         0.5        0.66666667 0.75      ]
[ 0  1  8 81]
(2)array与常数的运算存在广播机制:
print(a*2)
print(a**2)
print(a + 1)
print(a + 1.0)

结果:
[0 2 4 6]
[0 1 4 9]
[1 2 3 4]
[1. 2. 3. 4.]
(3)函数运算
print(np.sin(a), np.cos(a), np.tan(a))
print(np.sinh(a), np.cosh(a), np.tanh(a))
print(np.exp(a)) 
print(np.log2(b)) 
# log = ln
print(np.log(b)) 
# log10 = lg
print(np.log10(b))

结果:
[0.         0.84147098 0.90929743 0.14112001] [ 1.          0.54030231 -0.41614684 -0.9899925 ] [ 0.          1.55740772 -2.18503986 -0.14254654]
[ 0.          1.17520119  3.62686041 10.01787493] [ 1.          1.54308063  3.76219569 10.067662  ] [0.         0.76159416 0.96402758 0.99505475]
[ 1.          2.71828183  7.3890561  20.08553692]
[0.        1.        1.5849625 2.       ]
[0.         0.69314718 1.09861229 1.38629436]
[0.         0.30103    0.47712125 0.60205999]
(4)逻辑与位运算
print(a > 2, a >= 2, a == 2)
print(a & 1, a | 1, ~a)

结果:
[False False False  True] [False False  True  True] [False False  True False]
[0 1 0 1] [1 1 3 3] [-1 -2 -3 -4]
2.矩阵运算(二维数组)
>>> A = np.arange (1,5).reshape (2,2)
>>> B = np.arange (0,4).reshape (2,2)
>>>> print(A)
[[1 2]
 [3 4]]
>>> print(B)
[[0 1]
 [2 3]]
>>> np.multiply(A,B)
array([[ 0,  2],
       [ 6, 12]])
>>> np.multiply(np.mat(A),np.mat(B))     #mat创建矩阵
matrix([[ 0,  2],
        [ 6, 12]])
>>> np.sum(np.multiply(np.mat(A),np.mat(B)))    #sum将全部元素相加
20
>>> np.dot(A,B)     #矩阵点乘另一种方法
array([[ 4,  7],
       [ 8, 15]])
>>> C = np.arange (1,4)
>>> D = np.arange (0,3)
>>> np.dot(C,D)
8
>>> np.dot(C.reshape (3,-1).T, D.reshape (3,-1))    #.T可进行转置
array([[8]])
>>> np.dot(np.mat(A),np.mat(B))
matrix([[ 4,  7],
        [ 8, 15]])
3.非数组运算,调用方法
a = np.random.randint(0,5,(2,3))
print a
print a.sum(),a.sum(axis=1),a.sum(0) # axis用于指定运算轴(默认全部,可指定0或1)
print a.min(),a.max(axis=1),a.mean(axis=1) # axis = 0: 按列计算,axis = 1: 按行计算
print a.cumsum(1) # 按行计算累积和

 

[[2 3 3]
 [0 2 1]]
11 [8 3] [2 5 4]
0 [3 2] [ 2.66666667  1.        ]
[[2 5 8]
 [0 2 3]]

五、其他

1.特殊矩阵
>>> np.eye(5)    #单位矩阵
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.]])
>>> A
array([[1, 2],
       [3, 4]])
>>> np.linalg.inv(A)    #矩阵求逆
array([[-2. ,  1. ],
       [ 1.5, -0.5]])
>>> np.linalg.det(A)    #计算行列式
-2.0000000000000004
>>> A_inv * A_det    #伴随矩阵:A*=|A|A^(-1)
array([[ 4., -2.],
       [-3.,  1.]])
>>> A.T    #矩阵转置
array([[1, 3],
       [2, 4]])
2.一维数组
a = np.arange(0,10,1)**2
print a
print a[0],a[2],a[-1],a[-2] # 索引从0开始,-1表示最后一个索引
print a[2:5],a[-5:-1] # 包括起点,不包括终点
a[-1] = 100; print a # 赋值
a[1:4]=100; print a # 批量赋值
a[:6:2] = -100; print a # 从开始到第6个索引,每隔一个元素(步长=2)赋值
print a[: :-1];print a # 将a逆序输出,a本身未发生改变
b = [np.sqrt(np.abs(i)) for i in a]; print b # 通过遍历赋值

  

[ 0  1  4  9 16 25 36 49 64 81]
0 4 81 64
[ 4  9 16] [25 36 49 64]
[  0   1   4   9  16  25  36  49  64 100]
[  0 100 100 100  16  25  36  49  64 100]
[-100  100 -100  100 -100   25   36   49   64  100]
[ 100   64   49   36   25 -100  100 -100  100 -100]
[-100  100 -100  100 -100   25   36   49   64  100]
[10.0, 10.0, 10.0, 10.0, 10.0, 5.0, 6.0, 7.0, 8.0, 10.0]
3.多维数组
a = np.arange(0,20).reshape((4,5))
print a, a[2,3], a[:,1], a[1:4,2], a[1:3,:]
print a[-1] # 相当于a[-1,:],即索引少于轴数时,确实的索引默认为整个切片

b = np.arange(0,24).reshape((2,3,4))
print b,b[1] # 相当于b[1,:,:] 和b[1,...]
print '-------------------'
for row in a:
    print row # 遍历以第一个轴为基础

 

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

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

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

[0 1 2 3 4]
[5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
4.reshape和resize
a = np.array([[1,2,3],[4,5,6]])
b = a
a.reshape((3,2))# 不改变数组本身的形状
print a
b.resize((3,2))# 改变数组本身形状
print b

  

[[1 2 3]
 [4 5 6]]
[[1 2]
 [3 4]
 [5 6]]

在numpy模块中,我们经常会使用resize 和 reshape,在具体使用中,通常是使用resize改变数组的尺寸大小,使用reshape用来增加数组的维度。

1.resize

之前看到别人的博客说,resize没有返回值,其实这取决于你如何使用resize,resize有两种使用方式,一种是没有返回值的,直接对原始的数据进行修改,还有一种用法是有返回值的,所以不会修改原有的数组值。

1.1有返回值,不对原始数据进行修改

import numpy as np
X=np.array([[1,2,3,4],
              [5,6,7,8],
              [9,10,11,12]])
 
X_new=np.resize(X,(3,3)) # do not change the original X
print("X:\n",X)  #original X
print("X_new:\n",X_new) # new X
 
>>
X:
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
X_new:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]

1.2 无返回值,直接修改原始数组的大小

import numpy as np
X=np.array([[1,2,3,4],
              [5,6,7,8],
              [9,10,11,12]])
 
X_2=X.resize((3,3))  #change the original X ,and do not return a value
print("X:\n",X)  # change the original X
print("X_2:\n",X_2) # return None
 

 
X:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]
X_2:
 None

2.reshape

给数组一个新的形状而不改变其数据

import numpy as np
X=np.array([1,2,3,4,5,6,7,8])
 
X_2=X.reshape((2,4)) #retuen a 2*4 2-dim array
X_3=X.reshape((2,2,2)) # retuen a 2*2*2 3-dim array
 
print("X:\n",X)
print("X_2:\n",X_2)
print("X_3:\n",X_3)
 
>>
X:
 [1 2 3 4 5 6 7 8]
X_2:
 [[1 2 3 4]
 [5 6 7 8]]
X_3:
 [[[1 2]
  [3 4]]
 
 [[5 6]
  [7 8]]]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值