Python(2) -numpy 的常规函数
参考:
https://www.runoob.com/numpy/numpy-terating-over-array.html
0、初始化构造
numpy中的ndarray“看起来”可以存放不同类型的数据,不过正常业务使用中一般存放同类型的数据用于计算。
之所以说“看起来”,是因为如果其中传进来了不同的类型,则统一视为同一类型,优先级:str > float > int
而且如果ndarray中存放字符串,所有字符串占用空间大小都相同,构建的时候以最长字符串的长度为准,短的字符串则补0。赋值的时候超过长度会截断。
import numpy as np
np.ndim #维度
## 使用列表或元组创建
np.array([[1, 2], [3, 4], (5, 6)])
np.array([-1,5.6,4],dtype="int") #初始化时,定义其类型,不同类型会转换。
## 使用方法创建
# 生成指定维度的全1数组
np.ones(shape)
# 生成指定维度的全0数组
np.zeros(shape)
# 生成指定维度的全为单一指定值的数组
np.full(shape, val)
# 生成n*m的矩阵,且对角线为1,其余为0
np.eye(n,m)
# 根据数组a的形状生成全1数组
np.ones_like(a)
# 依据数组a的形状生成全0数组
np.zeros_like(a)
# 依据数组a的形状生成全为单一指定值的数组
np.full_like(a, val)
''' 数组的维度变换 '''
# 返回重新指定shape的数组,原数组不变
.reshape(shape)
# 同.reshape(),但改变原数组
.resize(shape)
''' 数据类型转化 '''
# 将数组转化为列表
.tolist()
# 转换为其他数据类型,原数组不变
.astype(new_type)
#np.arange(12) # 0~12
#np.arange(12).reshape(3,4) # 一个3*4的2维数据
#从迭代器构建
obj = {"name":8,"age":23,"money":89}
x = np.fromiter(obj.values(),dtype="S20") #S20表示定长20的字符串。
print(x)
output>>[b'8' b'23' b'89']
常用的一些属性
ndim 矩阵的秩
dtype矩阵的类型
itemsize 每个元素的大小
flags 对象的内存信息
数据类型:
bool_
int_ 默认整型
intc 与 C 的 int 类型一样,一般是 int32 或 int 64
intp 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64
int8 亦写作 i1
int16 亦写作 i2
int32 亦写作 i4
int64 亦写作 i8
uint8 亦写作 u1
uint16 亦写作 u2
uint32 亦写作 u3
uint64 亦写作 u4
float_ 亦写作 f8 |
float16 亦写作 f2
float32 亦写作 f4
float64 亦写作 f8
complex_
complex64
complex128
1、数组的切片
0、给定数组
import numpy as np
x1 = np.arange(6) # 一维数据
output >> [ 0 1 2 3 4 5 ]
x2 = np.arange(12).reshape(3,4) # 一个3*4的2维数据
output >>
[[0 1 2 3]
[4 5 6 7]
[8 9 10 11]]
1、一维数组普通切片
print(x1[2:5])
#output >>
[2 3 4]
print(x1[1:6:2])
#start-1, end-6, gap-2
#output >>
[1 3 5]
2、二维数组切片
print(x2[1])
print(x2[1,...])# 三个点表示该维度全部选择
print(x2[1,])
#以上三个相同,都输出第二行
output >>
[4 5 6 7]
print(x2[...,1]) #输出第二列
#这里不能用x2[,1]
#output >>
[1 5 9]
print(x2[...,1:3]) #输出第二 三列
output >>
[[1 2]
[5 6]
[9 10]]
通过row和col的索引,将数据输出到一个数组中:
print(x2[[1,2,1,0,0,2,1],[2,3,0,1,2,3,0]]) //展示一组数据,行的idx在前,列的idx在后
output >>
[ 6 11 4 1 2 11 4]
以上的输出是一个一维数组,如果想输出为二维数组,可以:
rows = np.array([[0,0,1,2,1,1,0],[2,1,1,0,1,2,0]])
cols = np.array([[0,2,3,1,1,2,0],[1,3,2,0,0,0,2]])
print(x2[rows,cols])
output >>
[[0 2 7 9 5 6 0]
[9 7 6 0 4 8 2]]
以上2个是离散输出,如果需要连续输出:
print(x2[0:2,1:4]) #从行0~1,从列1~3,连续截取
output >>
[[1 2 3]
[5 6 7]]
print(x2[0:2,[1,3]]) #从行0~1连续截取,列1和3离散截取
output >>
[[1 3]
[5 7]]
布尔索引
print(x2[x2>5])#输出大于5的元素,输出为一个一维数组
output>>
[ 6 7 8 9 10 11]
nan的判断索引:
2、数组广播
一般情况下同shape的数组,可以直接做一些运算,如 + - * /。
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([0,1,2])
print(a + b)
output >>
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
b = np.array([[0],[1],[2],[5]])
print(a + b)
output >>
[[ 0 0 0]
[11 11 11]
[22 22 22]
[35 35 35]]
注意,广播的时候,小数组的维度必须有一个是1,小数组必须匹配大数组的对饮维度的长度。否则不会广播
3、数组迭代 nditer
1、普通打印
import numpy as np
a = np.arange(6).reshape(2,3)
#output >>
# [[0,1,2],
# [3,4,5]
# ]
for x in np.nditer(a):
print (x, end=", " )
print ('\n')
#0, 1, 2, 3, 4, 5,
for x in np.nditer(a,order="F"): #F表是Fortran,列序优先
print (x, end=", " )
print ('\n')
#0, 3, 1, 4, 2, 5,
for x in np.nditer(a,order="C"): #C表是C语言order,行序优先,默认就是这个
print (x, end=", " )
print ('\n')
#0, 1, 2, 3, 4, 5,
for x in np.nditer(a.T): #转置其实依然共享的同一段内存,并不会copy新内存
print (x, end=", " )
print ('\n')
#0, 1, 2, 3, 4, 5,
for x in np.nditer(a.T.copy()):#转置的拷贝是新内存
print (x, end=", " )
print ('\n')
#0, 3, 1, 4, 2, 5,
2、可修改
默认情况下nditer是只读的,如果需要修改,则需要设置op_flags=['readwrite'],如下:
import numpy as np
a = np.arange(6).reshape(2,3)
for x in np.nditer(a,op_flags=['readwrite']):
x[...]= x*2; # 这里的...是必须的,不过没太理解什么意思。这里的x的类型居然是<class 'numpy.ndarray'>,具体看下面文字解释。
print (a)
output>>
[[ 0 2 4]
[ 6 8 10]]
3、ndarray中的nditer遍历出来的数据,为什么依然是ndarray类型,而不某一个值类型
numpy.nditer 是 NumPy 中的一个功能强大的迭代器,用于遍历多维数组的元素。当你使用 nditer 遍历数组时,虽然你实际上是在逐个访问数组的元素,但这些元素在被访问时仍然保持为 NumPy 的 ndarray 类型。这是因为在 nditer 的设计上,它返回的是指向数组内部元素的指针,而不是直接的值。
举个例子,如果你有一个一维数组 a = np.array([1, 2, 3]),使用 nditer 遍历它时,虽然每个迭代步骤返回的是单个整数,但这些整数实际上是数组 a 中对应位置的值,因此它们仍然是 ndarray 类型。
这里的关键是,nditer 返回的是元素的值,而不是元素本身。在 Python 中,整数、浮点数等基本数据类型是不可变的,因此当你从 nditer 获取一个值时,这个值实际上是一个指向原始数组中相应位置的引用,而不是一个新的、独立的对象。
如果你想获取每个元素的值而不是 ndarray 对象,你可以在遍历过程中将元素转换为其他类型,例如将整数转换为字符串。这样,每个元素都会被转换为一个新的对象(在这个例子中是字符串),而不是原始数组的引用。
总结一下,nditer 返回的元素仍然是 ndarray 类型,是因为它返回的是指向数组内部元素的指针,而不是元素本身的副本。如果你希望获得元素的副本(例如将整数转换为字符串),你需要手动进行转换。
4、使用外部循环
flags = ['external_loop']
当设置 flag 为 external_loop 时,numpy.nditer 将只遍历数组的最外层维度,而忽略内部维度。
具体用法:
import numpy as np
a = np.arange(0,12)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
print ('修改后的数组是:')
for x in np.nditer(a, flags = ['external_loop'], order = 'C'):
print (x, end=", " )
print("mydiv")
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print (x, end=", " )
print("mydiv")
output>>
原始数组是:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
修改后的数组是:
[ 0 1 2 3 4 5 6 7 8 9 10 11], mydiv
[0 4 8], mydiv
[1 5 9], mydiv
[ 2 6 10], mydiv
[ 3 7 11], mydiv
这个比较难理解。根据代码理解:
对于【上述order="C"的情景】,将非外部数据看做一个整体,一次性输出。只有遍历完后才触及最外层的维度末尾。
对于上述order="F",由于竖着打印,所以每次都会初级外层维度的末尾,因此打印了4次。
4、数组的元素迭代器
之前的nditer迭代器中的内容是数组。flat迭代器中的内容就是元素本身。
import numpy as np
#每行打印
a = np.arange(9).reshape(3,3)
print ('原始数组:')
for row in a:
#print(type(row)) #这里的类型是ndarray,跟nditer一样的类型
print (row) #[0 1 2 ] [。。。。]......
'''
[[0 1 2]
[ 3 4 5]
[ 6 7 8]]
'''
#flat 获取元素迭代器
print ('迭代后的数组:')
for element in a.flat:
#print(type(element)) #这里的类型是int类型,也就是元素的类型
print (element) #0 1 2 3.........
#flatten 获取一个平铺数组。返回一个新数组,不影响原数组
b = a.flatten()
print(b) #[0 1 2 3 4 5 6 7 8 ]
b = a.flatten(order="F")
print(b) #[0 3 6 1 4 7 2 5 8]
#ravel 获取一个平铺数组,跟flatten差不多。返回引用,如果修改了返回的数组,那么原数组也会同步修改
b = a.ravel()
print(b)
#b[0] = 100 #如果修改了b[0],那么a[0][0]也会被修改。
#print(a)
5、数组的其他操作
(1)翻转
import numpy as np
a = np.arange(12).reshape(3,4)
print(a)
'''
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
'''
#transpose 翻转
b=np.transpose(a) #返回的是一个引用,不是复制体
#b = a.T #用T也是一样的效果
print (b)
'''
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
'''
(2)rollaxis滚动轴
a = np.arange(24).reshape(2,3,4)
print(a)
'''
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
'''
b = np.rollaxis(a,2,start=0) #第二个参数表示要滚动的轴,第三个参数表示将该轴滚动到的位置 默认0。
print(b)
# 将原来的最后一个维度变成了第一个维度。
'''
[[[ 0 4 8]
[12 16 20]]
[[ 1 5 9]
[13 17 21]]
[[ 2 6 10]
[14 18 22]]
[[ 3 7 11]
[15 19 23]]]
'''
(3)swapaxes交换轴
a = np.arange(24).reshape(2,3,4)
print(a)
'''
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
'''
b = np.swapaxes(a,1,2)
print(b)
# 将1 2 的两个维度交换。
'''
[[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[[12 16 20]
[13 17 21]
[14 18 22]
[15 19 23]]]
'''
(4)广播
a = np.arange(4).reshape(1,4)
'''
[[0 1 2 3]]
'''
print (np.broadcast_to(a,(4,4))) #维度必须匹配,才能自动广播
'''
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
'''
(5)维度拓展/删除
expand_dims(arr, axis)
a = np.arange(6).reshape(2,3)
b = np.expand_dims(a,0)#在0轴增加一个维度
print(b)
'''
[[[0 1 2]
[3 4 5]]]
'''
squeeze(arr, axis)
a = np.arange(24).reshape(1,2,3,4)
'''
[[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]]
'''
b = np.squeeze(a,0)#将0轴删除,这个必须是一维条目
print(b)
'''
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
'''
6、数组的连接
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b)))
print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))
沿轴 0 连接两个数组:
[[1 2]
[3 4]
[5 6]
[7 8]]
沿轴 1 连接两个数组:
[[1 2 5 6]
[3 4 7 8]]
除了,concatenate外,还有stack hstack vstack等函数,可以用来堆叠。
7、数组的切割
a = np.arange(9)
>> [0 1 2 3 4 5 6 7 8]
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
>> [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
>> [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
除了split外,还有hsplit和vsplit。
8、数组的插入删除
append
a = np.array([[1,2,3],[4,5,6]])
print ('第一个数组:')
print (a)
print ('\n')
print ('向数组添加元素:')
print (np.append(a, [7,8,9]))
print ('\n')
print ('沿轴 0 添加元素:')
print (np.append(a, [[7,8,9]],axis = 0))
print ('\n')
print ('沿轴 1 添加元素:')
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
第一个数组:
[[1 2 3]
[4 5 6]]
向数组添加元素:
[1 2 3 4 5 6 7 8 9]
沿轴 0 添加元素:
[[1 2 3]
[4 5 6]
[7 8 9]]
沿轴 1 添加元素:
[[1 2 3 5 5 5]
[4 5 6 7 8 9]]
insert
a = np.array([[1,2],[3,4],[5,6]])
print ('第一个数组:')
print (a)
print ('\n')
print ('未传递 Axis 参数。 在删除之前输入数组会被展开。')
print (np.insert(a,3,[11,12]))
print ('\n')
print ('传递了 Axis 参数。 会广播值数组来配输入数组。')
print ('沿轴 0 广播:')
print (np.insert(a,1,[11],axis = 0))
print ('\n')
print ('沿轴 1 广播:')
print (np.insert(a,1,11,axis = 1))
第一个数组:
[[1 2]
[3 4]
[5 6]]
未传递 Axis 参数。 在删除之前输入数组会被展开。
[ 1 2 3 11 12 4 5 6]
传递了 Axis 参数。 会广播值数组来配输入数组。
沿轴 0 广播:
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
沿轴 1 广播:
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
delete
删除操作类似:
Numpy.delete(arr, obj, axis)
9、数学运算
以三角函数为例:
a = np.array([0,30,45,60,90])
print ('不同角度的正弦值:')
# 通过乘 pi/180 转化为弧度
print (np.sin(a*np.pi/180))
print ('\n')
print ('数组中角度的余弦值:')
print (np.cos(a*np.pi/180))
print ('\n')
print ('数组中角度的正切值:')
print (np.tan(a*np.pi/180))
不同角度的正弦值:
[0. 0.5 0.70710678 0.8660254 1. ]
数组中角度的余弦值:
[1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
6.12323400e-17]
数组中角度的正切值:
[0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
1.63312394e+16]
其他的数学运算
四舍五入: numpy.around()
向下取整:numpy.floor()
向上取整:numpy.ceil()
指数运算:numpy.power()
余数:numpy.mod()
加减乘除: add(),subtract(),multiply() 和 divide()
倒数:numpy.reciprocal()
100、tile 平铺
参考:https://blog.csdn.net/weixin_41998772/article/details/113563806
用法tile(A, reps)
tile是平铺的意思。即将数组A是为瓷砖,在一个二维平面reps平铺开来
0、给定一个数组
from numpy import *
c = array([[1,2],[3,4]])
print(c)
Output:
[[1 2]
[3 4]]
1、横向平铺
print(tile(c,4))
#等效为print(tile(c,(1,4)))
Output:
[[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]]
2、纵向平铺
print(tile(c,(3,1)))
Output:
[[1 2]
[3 4]
[1 2]
[3 4]
[1 2]
[3 4]]
3、横向纵向平铺
print(tile(c,(3,4)))
Output:
[[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]
[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]
[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]]
101、sum max min 最值 等统计函数
计算某一维的sum值,同时该维消失。
0、给定一个数组
import numpy as np
b = np.arange(24).reshape(2,3, 4) # 一个2*3*4的三维数据
print(b)
output >>
[[[ 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、计算某一维的sum
print(b.sum(axis=0)) #0维(0~2)
output >>
[[12 14 16 18]
[20 22 24 26]
[28 30 32 34]]
print(b.sum(axis=1)) #1维(0~2)
output >>
[[12 15 18 21]
[48 51 54 57]]
2、计算某一维的max
print(b.max(axis=1)) #1维(0~2
[[ 8 9 10 11]
[20 21 22 23]]
min max跟numpy.amin amax函数是一样的,只是调用方式不同。
初次之外,还有一下统计函数:
numpy.ptp() 计算数组中元素最大numpy.percentile()值与最小值的差(最大值 - 最小值)。
numpy.percentile()表示小于这个值的观察值的百分比
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)
numpy.mean() 函数返回数组中元素的算术平均值,如果提供了轴,则沿其计算。
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。
np.std 标准差
np.var方差
102、argsort 索引 排序等
(一)argsort函数返回的是数组值从小到大的索引值
1、一维数组
import numpy as np
x = np.array([8,7,9,4,5,3,10,1,20])
print(np.argsort(x)) #or use x.argsort()
output>>
[7 5 3 4 1 0 2 6 8]
2、多维数组
import numpy as np
b = np.arange(24).reshape(2,3, 4) # 一个2*3*4的三维数据
b = np.array([[[ 8, 5, 7, 5],
[45, 2,67, 5],
[ 4,12,98,45]],
[[ 4,89,90,87],
[ 4, 6, 8,11],
[ 5, 6, 1, 6]]])
print(np.argsort(b,axis=1)) #or use print(b.argsort(axis=1)) 从小到大
output >>
[[[2 1 0 0]
[0 0 1 1]
[1 2 2 2]]
[[0 1 2 2]
[1 2 1 1]
[2 0 0 0]]]
print(np.argsort(-b,axis=1)) #or use print(-b.argsort(axis=1)) 从大到小
output>>
[[[1 2 2 2]
[0 0 1 0]
[2 1 0 1]]
[[2 0 0 0]
[0 1 1 1]
[1 2 2 2]]]
(二)numpy.sort进行排序
a = np.array([[3,7],[9,1]])
>>
[[3 7]
[9 1]]
print (np.sort(a))
>> #默认验证最后一个轴排序
[[3 7]
[1 9]]
print (np.sort(a, axis = 0))
>>
[[3 1]
[9 7]]
除此之外,还有lexsort()、msort、sort_complex、partition、argpartition等。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)