Python作为目前比较热门的编程语言,无论是应用在人工智能领域还是数据处理领域都能胜任绝大部分工作,尤其是对数据进行读取、清洗、展示等操作时更能让使用者感觉得心应手,本文将详细的对Python语言中的numpy库进行梳理和举例,作为自己的学习笔记供大家参考,如有不足或错误之处还请各位读者指出,感谢阅读
ndarray对象:实际上是一个多维的数组对象,该对象由两个部分组成:
Numpy数组一般是同质的(除了一种特殊的数组类型外),也就是说数组中的所有元素类型必须是一致的。
# 创建多维数组
import numpy as np
np.array([[[arange(2)],[arange(3)]]])
# 二维数组a
a = np.array([[1,2],[3,4]])
# 读取数组a中的数字
a[0,1]
a[1,1]
# 类型转换
float64(42)
np.arange(10, dtype=float32)
# 数据类型对象
a.dtype.itemsize # 可以查看单个数组元素在内存中占用的字节数
#创建自定义数据类型
#1.创建数据类型
t = dtype([('name',str_, 40), ('numitems', int32), ('price', float32)])
print(t)
# 2.查看数据类型
t['name']
知识点:
np.arange(24).reshape(2,3,4)
reshape()函数的作用是人为的为数据设定结构,即两行三列,每个组中有4个数据
a = arange(7)
# 按照索引切
a[:6]
# 规定步长
a[::2]
a[::-1] # 可以逆序输出
# 多维数组的切片和索引
b = np.arange(24).reshape(2,3,4)
# 此时的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]]])
b[0,2,3] # 第一个代表是第几层 第二个数代表行 第三个数代表列
# 若要选择第二层楼中的所有房间
b[1,:,:] # 可用:代替全选
b[1,...] # 也可以用省略号代替多个:
b[1,:,::2] # 按照步长选择数据
b[0,::-1,-1] # 11 7 3
b[::-1] # 对b进行了倒序输出
ravel()
,将数组展平
flatten
,这个函数与ravel()
功能相同,但该函数会请求分配内存来保存结果,ravel()
函数只是返回一个视图(view)
用元组设置维度 b.shape = (6,4)
,除了可以使用reshape()函数,还可以直接使用正整数元组来设置数组的维度。该方法可以直接操作原数据,对其进行修改
transpose()
在线性代数中,转置矩阵是很常见的操作,对于多维数组也可以这样,通过该函数进行转置
resize()
这个函数和reshape()
函数作用相同,但该函数会直接修改数据
b.ravel()
# 展平后的结果
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])
b.flatten()
# 展平后的结果
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])
b.shape = (6, 4)
# 结果
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]])
b.transpose()
# 结果
array([[ 0, 4, 8, 12, 16, 20],
[ 1, 5, 9, 13, 17, 21],
[ 2, 6, 10, 14, 18, 22],
[ 3, 7, 11, 15, 19, 23]])
b.resize((2, 12))
# 结果
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]])
水平组合:可以直接将数组当做参数传递给hstack()
,或者通过concatenate()
函数来实现
垂直组合:可以直接将数组当做参数传递给vstack()
,或者通过concatenate()
函数来实现
深度组合:将相同的元组作为参数传给dstack()
函数,即可完成数组的深度组合。所谓深度组合,就是将一系列数组沿着纵轴(深度)方向进行层叠组合。举个例子,有若干张二维平 面内的图像点阵数据,我们可以将这些图像数据沿纵轴方向层叠在一起,这就形象地解释了什么是深度组合
列组合:column_stack()
函数对一维数组将按照列方向进行组合;对于二维数组则是和hstack()
效果完全相同的
行组合:row_stack()
函数对于两个一维数组,将直接层叠起来组合成一个二维数组。
a = arange(9).reshape(3,3)
b = 2 * a
# a 与 b
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
array([[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
# 1.水平组合
hstack((a,b))
concatenate((a,b) ,axis=1)
# 结果
array([[ 0, 1, 2, 0, 2, 4],
[ 3, 4, 5, 6, 8, 10],
[ 6, 7, 8, 12, 14, 16]])
# 2.垂直组合
vstack((a,b))
concatenate((a,b))
#结果
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
# 3.深度组合
dstack((a,b))
# 结果
array([[[ 0, 0],
[ 1, 2],
[ 2, 4]],
[[ 3, 6],
[ 4, 8],
[ 5, 10]],
[[ 6, 12],
[ 7, 14],
[ 8, 16]]])
# 4.列组合
oned = arange(2)
twice_oned = 2 * oned
# 数据
array([0, 1])
array([0, 2])
column_stack((oned, twice_oned))
# 结果
array([[0, 0],
[1, 2]])
column_stack((a,b)) == hstack((a,b)) #也就是说可以直接用 == 来判断两个numpy数组是否相等
# 结果
array([[ True, True, True, True, True, True],
[ True, True, True, True, True, True],
[ True, True, True, True, True, True]])
# 5.行组合
row_stack((oned,twice_oned))
# 结果
array([[0, 1],
[0, 2]])
row_stack((a,b)) # 对二维数组使用的话等同于vstack()
# 结果
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
numpy数组可进行水平、垂直或深度分割,相关的函数有 hsplit、vsplit、dsplit和split
,可以将数组分割成相同大小的子数组,也可以指定原数组中需要分割的位置。
# 1. 水平分割 hsplit(), split()
print(hsplit(a, 3)) # 将数组沿着水平方向分割成3个相同大小的子数组
print(split(a, 3, axis=1)) # 也可以调用split函数并在参数中指定axis=1
# 结果
[array([[0],
[3],
[6]]), array([[1],
[4],
[7]]), array([[2],
[5],
[8]])]
[array([[0],
[3],
[6]]), array([[1],
[4],
[7]]), array([[2],
[5],
[8]])]
# 2.垂直分割 vsplit()
print(vsplit(a, 3)) # 将数组按照垂直方向进行分割
print(split(a, 3, axis=0))
# 结果
[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
# 3.深度分割 dsplit() 创建一个新的三维数组
c= np.arange(27).reshape(3,3,3)
# 结果
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]]])
# 按照深度进行分割
dsplit(c, 3)
#结果
[array([[[ 0],
[ 3],
[ 6]],
[[ 9],
[12],
[15]],
[[18],
[21],
[24]]]),
array([[[ 1],
[ 4],
[ 7]],
[[10],
[13],
[16]],
[[19],
[22],
[25]]]),
array([[[ 2],
[ 5],
[ 8]],
[[11],
[14],
[17]],
[[20],
[23],
[26]]])]
除了shape
和dtype
属性,ndarray
对象还有其他属性:
ndim
属性,给出数组的维数,或者数组轴的个数b = arange(24).reshape(1,24)
# 结果
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]])
b.ndim
# 结果
2
size
属性,给出数组元素的总个数b.size
# 结果
24
itemsize
属性,给出数组中的元素在内存中所占的字节数b.itemsize
# 结果
4
nbytes
属性,查看整个数组所占的存储空间数,其实就是itemsize
和size
属性值的乘积b.nbytes
b.size * b.itemsize
# 结果
96
96
T
属性,等同于transpose
的效果b.resize(6, 4)
# 结果
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]])
b.T
# 结果
array([[ 0, 4, 8, 12, 16, 20],
[ 1, 5, 9, 13, 17, 21],
[ 2, 6, 10, 14, 18, 22],
[ 3, 7, 11, 15, 19, 23]])
# 需要注意的是对于一维数组,它的T属性就是原数组
j
来表示的,可以通过这种方法来创建复数数组b = array([1.j + 1, 2.j + 3])
# 结果
array([1.+1.j, 3.+2.j])
real
属性,给出复数数组的实部;如果数组中只包含实数元素,则其real属性将输出原数组b.real
# 结果
array([1., 3.])
imag
属性,给出复数数组的虚部b.imag
# 结果
array([1., 2.])
b.dtype
# 结果
dtype('complex128')
flat
属性将返回一个numpy.flatiter
对象,这是获得flatiter
对象的唯一方式——我们无法访问flatiter
的构造函数。这个所谓的扁平迭代器可以让我们遍历一维数组一样的去遍历任意多维数组a
# 结果
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
g = a.flat
g
# 结果
<numpy.flatiter at 0x2281162b8e0>
for item in g:
print(g)
# 结果
0
1
2
3
4
5
6
7
8
# 也可以直接用flatiter对象获取数组元素
a.flat[3]
# 结果
3
# 或者获取多个元素
a.flat[[-1,3]]
# 结果
array([8, 3])
# flat属性是一个可赋值的属性,对flat属性赋值将导致整个数组的元素都被覆盖
a.flat = 7
a.flat = [1,3,6]
# 结果
array([[7, 7, 7],
[7, 7, 7],
[7, 7, 7]])
array([[1, 3, 6],
[1, 3, 6],
[1, 3, 6]])
可以使用tolist
函数将numpy数组转换成Python列表
tolsit
转换成列表b = array([1.j + 1, 2.j + 3])
# 结果
array([1.+1.j, 3.+2.j])
b.tolist()
# 结果
[(1+1j), (3+2j)]
astype
可以指定转换后的数据类型b.astype(float)
# 结果
F:\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: ComplexWarning: Casting complex values to real discards the imaginary part
Entry point for launching an IPython kernel.
array([1., 3.])
# 在这一步中会报红,因为转换类型的途中丢失了虚部,如果正常操作则不会有报红
在本章中列举出了很多常见的numpy函数、数据类型numpy数组。对于数组而言, 有很多属性可以用来描述数组,数据类型就是其中之一。类似于Python列表,numpy数组也可以方便地进行切片和索引操作。在多维数组上,numpy有明显的优势。
在下一篇文章中,将开始学习numpy中的常用函数,包括基本数学函数和统计函数等,希望各位读者有所收获,感谢阅读。