NumPy数据操作归纳总结

NumPy是一个在Python中做科学计算的核心库,它提供了一个高性能的多维数组对象,以及用于处理这些数组的工具。

一、NumPy数据结构:数组(Arrays)

1、创建数组

NumPy数组是一个值网格,所有类型都相同,并由非负整数元组索引。数组的形状是一个整数元组,给出了每个维度的数组大小。

import numpy as np

# 按照给定数据生成普通数组
a1 = np.array([1, 2, 3])
a2 = np.array([[1,2,3],[4,5,6]])
print(a1.shape)

# 生成全0数组
c = np.zeros((2,2))

# 生成全1数组
d = np.ones((1,2))

# 生成全为指定值的数组
e1 = np.full((2,2), 7)
e2 = np.full((3, 3), True, dtype=bool)  # 创建一个布尔数组

# 生成指定维数的单位矩阵
f = np.eye(2) 

# 生成用0-1之间随机数填充的数组
g = np.random.random((2,2)) 

# 创建指定规律的数组
b1 = np.arange(20)  # 一维的长度20的数组,值范围为0到19
b2 = np.arange(2, 10) # 值范围2到10
b3 = np.arange(2, 3, 0.1)  # 值范围2到3,每次递增0.1
b4 = np.linspace(1,4,6)   # 创建具有指定数量元素的数组,并在指定的开始值和结束值之间平均间隔

2、数组索引

NumPy提供了几种索引数组的方法。

(1)整数枚举索引
import numpy as np 

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

# 整数枚举索引
print(a[1, 2])
# 7

print(a[[0,1,2], [0,0,0]])  # 对应组合
# [1,5,9]
print(a[[0,1,2], [0,1,0]])
# [1,6,9]

整数枚举索引的一个有用技巧是从矩阵的每一行中选择或改变一个元素。

import numpy as np 

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

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

print(a[np.arange(3), b])
# [1 7 10]

a[np.arange(3), b] += 10
print(a)
(2)布尔索引

通常,这种类型的索引用于选择满足某些条件的数组元素。

import numpy as np 

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

bool_idx = (a > 2)
print(bool_idx)
# [[False False  True  True]
#  [ True  True  True  True]
#  [ True  True  True  True]]

print(a[bool_idx])
# [3  4  5  6  7  8  9 10 11 12]
print(a[a > 2])
# [3  4  5  6  7  8  9 10 11 12]
(3)切片索引

我们可以对NumPy数组进行切片。由于数组可能是多维的,因此必须为数组的每个维指定一个切片。

import numpy as np 

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

# 序号为2的行之前(不包含)
# 序号为1的列及其之后(包含),序号为3的列之前(不包含)
b = a[:2, 1:3]
print(b)
# np.array([[2,3], 
#           [6,7]])

还可以将整数索引与切片索引混合使用。 但是,这样做会产生比原始数组更低级别的数组。

import numpy as np 

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

b1 = a[1, :]
print(b1)
# [5,6,7,8]
b2 = a[1:2, :]
print(b2)
# [[5,6,7,8]]

3、数组 I/O

NumPy 可以读写磁盘上的文本数据或二进制数据。

(1)numpy.save()+numpy.load()

NumPy 为 ndarray 对象引入了一个简单的文件格式:npy。npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。

import numpy as np 
 
a = np.array([1,2,3,4,5]) 
 
# 保存到 outfile.npy 文件上
np.save('outfile.npy',a) 

# 如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上
np.save('outfile',a)

# 读取.npy文件
b = np.load('outfile.npy') 
print(b)
(2)numpy.savze()+numpy.load()

numpy.savez() 函数将多个数组保存到以 npz 为扩展名的文件中。

import numpy as np 
 
a = np.array([[1,2,3],[4,5,6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)

# 保存到 outfile.npz 文件上, c 使用了关键字参数 sin_array
np.savez("outfile.npz", a, b, sin_array = c)

# 读取.npz文件
z = np.load("outfile.npz")  
print(z)
(3)numpy.savetxt()+numpy.loadtxt()

savetxt() 函数是以简单的文本文件格式存储数据,对应的使用 loadtxt() 函数来获取数据。

import numpy as np 
 
a = np.arange(0,10,0.5).reshape(4,-1)

# 保存到 outfile.txt 文件上, 以逗号分隔
np.savetxt("outfile.txt", a, delimiter=",")

# 读取 outfile.txt 文件,指定为逗号分隔
b = np.loadtxt("outfile.txt", delimiter=",")
print(b)

二、数组(Arrays)的基本操作

1、添加删除元素

(1)在末尾添加元素

append 函数在数组的末尾添加值。如果未提供轴,则输入数组会被展开。

import numpy as np
 
a = np.array([[1,2,3],[4,5,6]])
 
print(np.append(a, [7,8,9]))
# [1 2 3 4 5 6 7 8 9]

# 横向追加
print(np.append(a, [[5,5,5],[7,8,9]], axis = 1))
# [[1 2 3 5 5 5]
#  [4 5 6 7 8 9]]

# 纵向追加
print(np.append(a, [[7,8,9]], axis = 0))
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
(2)在指定位置插入元素

insert 函数在给定索引之前,沿给定轴在输入数组中插入值。如果未提供轴,则输入数组会被展开。

import numpy as np
 
a = np.array([[1,2,3],[4,5,6]])
 
print(np.insert(a, 2, [7,8,9]))
# [1 2 7 8 9 3 4 5 6]

# 横向插入
print(np.insert(a, 1, [11], axis = 1))
# [[ 1 11  2  3]
#  [ 4 11  5  6]]

# 纵向插入
print(np.insert(a, 1, [11], axis = 0))
# [[ 1  2  3]
#  [11 11 11]
#  [ 4  5  6]]
(3)删除特定元素

delete 函数用于返回从输入数组中删除指定索引的新数组。如果未提供轴参数,则输入数组将展开。

import numpy as np
 
a = np.array([[1,2,3],[4,5,6]])
 
print(np.delete(a, 5))
# [1 2 3 4 5]

# 删除行
print(np.delete(a, 1, axis = 0))
# [[1 2 3]]

# 删除列
print(np.delete(a, 1, axis = 1))
# [[1 3]
#  [4 6]]
(4)删除重复元素

unique 函数用于去除数组中的重复元素。

import numpy as np
 
a = np.array([5,2,6,2,7,5,6,8,2,9])
 
# 去重后数组 
print(np.unique(a))

# 返回去重数组的索引数组
u, indices = np.unique(a, return_index = True)
print(u, indices)

# 返回去重数组的下标
u, indices = np.unique(a,return_inverse = True)
print(u, indices)

# 返回去重元素重复数量
u, indices = np.unique(a, return_counts = True)
print(u, indices)

2、变换

(1)修改形状

reshape 函数有返回值,可以在不改变原数据的条件下修改形状。
resize 函数无返回值,会改变原数组的形状。

import numpy as np 

a = np.arange(8)
print(a)
# [0 1 2 3 4 5 6 7]

b = a.reshape(4,2)
print(b)
# [[0 1]
#  [2 3]
#  [4 5]
#  [6 7]]

b.resize(2,4)
print(b)
# [[0 1 2 3]
#  [4 5 6 7]]
(2)压平

ravel(散开,解开),flatten(变平),两者所要实现的功能是一致的(将多维数组降位一维)。

import numpy as np 

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

print(a.flatten())
# [0 1 2 3 4 5 6 7]
print(a.flatten(order = 'F'))
# [0 4 1 5 2 6 3 7]

print(a.ravel())
# [0 1 2 3 4 5 6 7]
print(a.ravel(order = 'F'))
# [0 4 1 5 2 6 3 7]

区别在于返回拷贝(copy)还是返回视图(view),flatten()返回的是一份拷贝,对拷贝所做的修改不会影响原始矩阵,而ravel()返回的是视图,会影响原始矩阵。

import numpy as np 

a = np.arange(8).reshape(2,4)

a.flatten()[1] = 10
print(a)
# [[0 1 2 3]
#  [4 5 6 7]]

a.ravel()[1] = 10
print(a)
# [[ 0 10  2  3]
#  [ 4  5  6  7]]
(3)转置

在处理一、二维数组时,ndarray.T 和 transpose()都可以实现矩阵转置效果。

import numpy as np 

a = np.arange(12).reshape(3,4)

print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

print(np.transpose(a))
# [[ 0  4  8]
#  [ 1  5  9]
#  [ 2  6 10]
#  [ 3  7 11]]
print(a.T)
# [[ 0  4  8]
#  [ 1  5  9]
#  [ 2  6 10]
#  [ 3  7 11]]

对于高维数组,需要用到 transpose() 和一个由轴编号组成的元组,才能进行转置。

import numpy as np

a = np.arange(12).reshape(2,2,3)
print(a.shape)  # 返回形状为(2, 2, 3), 可以对该元组进行索引, 也就是0,1,2

# 转置
print(a.transpose((1,0,2)))
(4)轴对换

swapaxes() 它接受一对轴编号,进行轴对换。

import numpy as np

a = np.arange(12).reshape(2,2,3)
print(a.shape)  # 返回形状为(2, 2, 3), 可以对该元组进行索引, 也就是0,1,2

# 交换0、1轴
print(a.swapaxes(1,0))
print(a.swapaxes(0,1))

# 交换0、2轴
print(a.swapaxes(0,2))
print(a.swapaxes(2,0))

2、修改数组维度

(1)增加维度
import numpy as np 

a = np.arange(9).reshape(3,3)

print(a.shape)
# (3, 3)

b1 = np.expand_dims(a, axis = 0)
print(b1.shape)
# (1, 3, 3)
b2 = np.expand_dims(a, axis = 1)
print(b2.shape)
# (3, 1, 3)
(2)删除一维条目
import numpy as np 

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

b = np.squeeze(a)
print(b.shape)
# (3, 3)
print(b)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]

3、数组合并与拆分

(1)hstack()、vstack()、concatenate()

hstack()用于横向堆叠序列中的数组,vstack()用于纵向堆叠序列中的数组。concatenate()支持按照指定轴堆叠数组序列,可实现前两者的功能。

import numpy as np 

a = np.array([[1, 2], 
              [3, 4]])
b = np.array([[5, 6],
              [7, 8]])

# 横向堆叠
h1 = np.hstack((a, b))
h2 = np.concatenate((a,b), axis = 1)
print(h1)
print(h2)
# [[1 2 5 6]
#  [3 4 7 8]]

# 纵向堆叠
v1 = np.vstack((a, b.T))
v2 = np.concatenate((a,b), axis = 0)
print(v1)
print(v2)
# [[1 2]
#  [3 4]
#  [5 7]
#  [6 8]]
(2)hsplit()、vsplit()、split()

hsplit()指定需要分裂的array数量对原array进行水平分裂,vsplit()需要分裂的array数量对原array进行垂直分裂。split()支持按照指定轴分裂数组序列,可实现前两者的功能。

import numpy as np 

a = np.arange(16).reshape(4,4)
print(a)

# 横向分割
print(np.hsplit(a, 2))
print(np.split(a, 2, axis = 1))

# 纵向分割
print(np.vsplit(a, 2))
print(np.split(a, 2, axis = 0))

3、排序

(1)numpy.sort()

numpy.sort() 函数返回输入数组的排序副本。

import numpy as np 

a = np.array([[6,2],
              [1,4]])

print(np.sort(a, axis=0, kind='quicksort'))
# axis=0按照列排序, axis=1按照行排序
# kind可选'quicksort'(快速排序)、'mergesort'(归并排序)、'heapsort'(堆排序)
(2)numpy.argsort()

numpy.argsort() 函数返回的是数组值从小到大的索引值。

import numpy as np 

a = np.array([5,  1,  7])
idx = np.argsort(a)
print(idx)
print(a[idx])
(3)numpy.lexsort()

numpy.lexsort() 用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。
这里举一个应用场景:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取…… 这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。

import numpy as np 

a = np.array([1,  5,  7])
b = np.array([2,  1,  5])
ind = np.lexsort((a,b))
ind2 = np.lexsort((b,a))

print(ind)
print([str(a[i])+","+str(b[i]) for i in ind])

print(ind2) 
print([str(a[i])+","+str(b[i]) for i in ind2])

4、搜索

(1)argmax() 、argmin()

argmax() 和 argmin()分别沿给定轴返回最大和最小元素的索引。

import numpy as np
 
a = np.array([[30,40,70],
              [80,20,10],
              [50,90,60]]) 

print(np.argmax(a))
print(np.argmax(a.flatten()))
# 7
print(np.argmin(a))
print(np.argmin(a.flatten()))
# 5

# 横向的最大最小索引
print(np.argmax(a, axis =  1))
print(np.argmin(a, axis =  1))

# 纵向的最大最小索引
print(np.argmax(a, axis =  0))
print(np.argmin(a, axis =  0)) 
(2)nonzero()

nonzero() 返回数组非零元素的索引。

import numpy as np
 
a = np.array([[0,40,70],
              [80,0,10],
              [50,90,0]]) 

idx = np.nonzero(a)

print(idx)
print(a[idx])
(3)where()、extract()

where() 函数返回输入数组中满足给定条件的元素的索引。
extract() 函数是直接返回满足条件的元素。

import numpy as np
 
a = np.array([[0,40,70],
              [80,0,10],
              [50,90,0]]) 

idx = np.where(a > 30)
print(a[idx])

condition = a > 30 
print(np.extract(condition, a))

三、数组(Arrays)的算术运算

1、加减乘除

简单的加减乘除: add(),subtract(),multiply() 和 divide()。

import numpy as np
 
a = np.arange(9).reshape(3,3)
b = np.array([10,10,10])

print(np.add(a,b))
# [[10 11 12]
#  [13 14 15]
#  [16 17 18]]

print(np.subtract(a,b))
# [[-10  -9  -8]
#  [ -7  -6  -5]
#  [ -4  -3  -2]]

print(np.multiply(a,b))
# [[ 0 10 20]
#  [30 40 50]
#  [60 70 80]]

print(np.divide(a,b))
# [[0.  0.1 0.2]
#  [0.3 0.4 0.5]
#  [0.6 0.7 0.8]]

2、倒数、幂和余数

import numpy as np 

a = np.array([0.25,  1.33,  1,  100])  

# 倒数
print(np.reciprocal(a))

# 幂
b = np.array([1,2,3,2])
print(np.power(a, 2))
print(np.power(a, b))

# 余数
print(np.mod(a, b))

3、三角函数

import numpy as np
 
a = np.array([0,30,45,60,90])

# 通过乘 pi/180 转化为弧度
print(np.sin(a*np.pi/180))

print(np.cos(a*np.pi/180))

print(np.tan(a*np.pi/180))

4、指数和对数

import numpy as np

a = np.array([1,30,45,60,90])

# 计算逐个元素的指数
print(np.exp(a))
# 计算逐个元素的指数 -1
print(np.expm1(a))

# 计算逐个元素的自然对数
print(np.log(a))
# 计算逐个元素的以10为底的对数
print(np.log10(a))

5、求和、求乘积

import numpy as np

a = np.array([1,30,45,60,90])

# 各元素的乘积
print(np.prod(a))
# 各元素的和
print(np.sum(a))

6、位运算

import numpy as np

# 数字的二进制表示
print(np.binary_repr(12, width = 8))
print(bin(12))

# 按位与
print(np.bitwise_and(12, 6))

# 按位或
print(np.bitwise_or(12, 6))

# 位取反运算
print(np.invert(np.array(12, dtype = np.uint8)))

四、数组(Arrays)的统计运算

1、最小值、最大值

amin() 用于计算数组中的元素沿指定轴的最小值。
amax() 用于计算数组中的元素沿指定轴的最大值。

import numpy as np
 
a = np.array([[3,7,5],
              [8,4,3],
              [2,4,9]])  

# 横向最小
print(np.amin(a, 1))
# [3 3 2]

# 纵向最小
print(np.amin(a, 0))
# [2 4 3]

# 横向最大
print(np.amax(a, 1))
# [7 8 9]

# 纵向最大
print(np.amax(a, 0))
# [8 7 9]

2、中位数、分位数、平均数、加权平均值

median() 函数用于计算数组中元素的中位数(中值)
percentile() 函数用于计算数组中元素的百分位数
mean() 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。
average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。

import numpy as np 

a = np.array([[30,65,70],
              [80,95,10],
              [50,90,60]]) 

print(np.median(a))
print(np.median(a, axis = 0))

print(np.percentile(a, 50))
print(np.percentile(a, 50, axis=0))

print(np.mean(a))
print(np.mean(a, axis = 0))

b = np.array([1,2,3,4])
wts = np.array([4,3,2,1])
print(np.average(b))
print(np.average(b, weights = wts))

3、标准差、方差

import numpy as np 
 
print(np.std([1,2,3,4]))
print(np.var([1,2,3,4]))

五、数组(Arrays)与线性代数

NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能。

1、范数

范数是对向量(或者矩阵)的度量,是一个标量(scalar)

import numpy as np 
 
a = np.array([3, 4])

# 二范数  5 
print(np.linalg.norm(a))
print(np.linalg.norm(a, ord=2))

# 一范数  7
print(np.linalg.norm(a, ord=1))

2、内积和外积

import numpy as np 
 
# 内积
a = np.array([[0.0, -1.0], 
              [1.0, 0.0]])
print(np.dot(a, a))

# 外积
b = np.arange(1,6)
print(np.multiply.outer(b, b))

3、逆矩阵

import numpy as np 

a = np.array([[1, 2],
              [-1,-3]])

print(np.linalg.inv(a))

4、特征值

import numpy as np 

a = np.array([[1, 2, 3],
              [-1,-3, 1]])

# 先进行矩阵的乘法,把矩阵和矩阵的转置相乘,得到一个方阵
U = np.dot(a, a.T)
# 把方阵作为输入,可以得到特征值和特征向量
lamda,hU = np.linalg.eig(U)
sigma = np.sqrt(lamda)
print(sigma)

# 用奇异值分解验证
Q,S,VT = np.linalg.svd(a)
print(S)

numpy中文文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349