1 多维数组adarray
程序示例:
b = np.zeros((2, 3, 5))
print(b)
print(b.ndim)
print(b.size)
print(b.shape)
执行结果:
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]]
3
30
(2, 3, 5)
结果解释: NumPy中的多维数组称为ndarray。其中:
ndim表示多维数组有几个维度。(程序示例中b有三个维度,每个维度的长分别为2、3、5)size是多维数组的长度,即数组中总共有多少个元素。(程序示例中b共有30个元素)shape是多维数组的型(即表示数组的形状),表示了数组的维数和每一维的元素的数量。(程序示例中b共有三个维度,这三个维度中元素个数分别为2个、3个、5个)
2 创建数组
最常用的方法是使用array()函数,该函数只有一个唯一的参数,需要传入一个数组类型的对象。 我们可以传入单层或多层列表,嵌套元组或元组列表,也可以是元组和列表组成的列表(或元组)。总之,传入的对象是数组类型即可。(Python的数组类型有列表List、元组Tuple、字典Dict、集合Set)
import numpy as np
# 嵌套的列表
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
# 嵌套的元组
b = np.array(((3, 2, 1), (6, 5, 4)))
print(b)
# 元组和列表组成的列表
c = np.array([(1, 2, 3), [4, 5, 6], (7, 8, 9)])
print(c)
# 元组和列表组成的元组
d = np.array(([3, 2, 1], (6, 5, 4), [9, 8, 7]))
print(d)
执行结果:
[[1 2 3]
[4 5 6]]
[[3 2 1]
[6 5 4]]
[[1 2 3]
[4 5 6]
[7 8 9]]
[[3 2 1]
[6 5 4]
[9 8 7]]
指定数组中的元素类型,可以设置array()的dtype参数,例如: 程序代码:
a = np.array([[1,2],[3,4]],dtype = 'D')
a
执行结果:
array([[1.+0.j, 2.+0.j],
[3.+0.j, 4.+0.j]])
3 数据类型
NumPy数组能够包含多种数据类型。
3.1 NumPy中的数据类型
NumPy包含的数值类型就有: 除了数值类型外,NumPy还支持一些其他类型,例如字符串等。
3.2 数据类型对象
数据类型对象是numpy.dtype类的实例。 函数array()、arange()都有参数dtype,可以通过设置dtype参数,设置各元素的数据类型。 程序代码:
import numpy as np
a1 = np.array((2,3))
print('a1 = ', a1)
a2 = np.array((2,3),dtype='f')#浮点型
print('a2 = ', a2)
b1 = np.arange(2,13,2)#间隔为2
print('b1 = ', b1)
b2 = np.arange(2,13,2,dtype='D') #复数型
print('b2 = ', b2)
执行结果:
a1 = [2 3]
a2 = [2. 3.]
b1 = [ 2 4 6 8 10 12]
b2 = [ 2.+0.j 4.+0.j 6.+0.j 8.+0.j 10.+0.j 12.+0.j]
3.3 自带的数组创建方法
zeros()
def zeros(shape, dtype=None, order=‘C’): Return a new array of given shape and type, filled with zeros. Parameters ---------- shape : int or tuple of ints Shape of the new array, e.g., (2, 3) or 2. dtype : data-type, optional The desired data-type for the array, e.g., numpy.int8. Default is numpy.float64. order : {‘C’, ‘F’}, optional, default: ‘C’ Whether to store multi-dimensional data in row-major (C-style) or column-major (Fortran-style) order in memory. Returns ------- out : ndarray Array of zeros with the given shape, dtype, and order.
ones() 与zeros()用法相同,只是以0填充。
def ones(shape, dtype=None, order=‘C’): Return a new array of given shape and type, filled with ones.
arange()
arange([start,] stop[, step,], dtype=None) Parameters ---------- start : number, optional Start of interval. The interval includes this value. The default start value is 0. stop : number End of interval. The interval does not include this value, except in some cases where step is not an integer and floating point round-off affects the length of out. step : number, optional Spacing between values. For any output out, this is the distance between two adjacent values, out[i+1] - out[i]. The default step size is 1. If step is specified as a position argument, start must also be given. dtype : dtype The type of the output array. If dtype is not given, infer the data type from the other input arguments. Returns ------- arange : ndarray
程序示例:
print(np.zeros((3,3)))
print()
print(np.ones((3,3),dtype='f'))
print()
print(np.arange(6))
print(np.arange(1,6))
print(np.arange(1,6,2))
执行结果;
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
[0 1 2 3 4 5]
[1 2 3 4 5]
[1 3 5]
linspace()
.def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None): “”" Return evenly spaced numbers over a specified interval. Returns num evenly spaced samples, calculated over the interval [start, stop]. The endpoint of the interval can optionally be excluded. Parameters ---------- start : scalar The starting value of the sequence. stop : scalar The end value of the sequence, unless endpoint is set to False. In that case, the sequence consists of all but the last of num + 1 evenly spaced samples, so that stop is excluded. Note that the step size changes when endpoint is False. num : int, optional Number of samples to generate. Default is 50. Must be non-negative. endpoint : bool, optional If True, stop is the last sample. Otherwise, it is not included. Default is True. retstep : bool, optional If True, return (samples, step), where step is the spacing between samples. dtype : dtype, optional The type of the output array. If dtype is not given, infer the data type from the other input arguments. … versionadded:: 1.9.0 Returns ------- samples : ndarray There are num equally spaced samples in the closed interval [start, stop] or the half-open interval [start, stop) (depending on whether endpoint is True or False). step : float, optional Only returned if retstep is True Size of spacing between samples.
linspace,默认使用起始闭区间[start,end]。 参数num表示默认划分成50份。 参数endpoint为True时,表示将端点end考虑在内。为False时,表示将端点end排除在外。 参数retstep为True时,表示返回生成数组中各元素的间隔。为False时,不返回间隔。 程序示例:
print(np.linspace(2,8,num=4))
print(np.linspace(2,8,num=4,retstep=True))
执行结果:
[2. 4. 6. 8.]
(array([2., 4., 6., 8.]), 2.0)
3.4 基本运算
3.4.1 算术运算符
加(+)、减(-)、乘(*) 均为元素级,即两个数组进行这三种运算,是各对应位置的元素,进行这些运算。
3.4.2 矩阵积
NumPy中用dot()函数表示矩阵积。
dot(a, b, out=None)
程序示例:
import numpy as np
a = np.arange(1, 4)
print('a = ', a)
b = np.linspace(1, 3, 3)
print('b = ', b)
print(np.dot(a, b)) # 即1*1+2+2+3+3 = 14
print(a.dot(b))
print(np.dot(b,a)) # 注意:矩阵积的运算不遵循交换律,所以运算对象的顺序很重要。此处的例子没有显示这一点,但还是要注意。
执行结果:
a = [1 2 3]
b = [1. 2. 3.]
14.0
14.0
14.0
3.4.3 自增和自减运算符
自增(+=)、自减( -=)。 程序示例:
a = np.arange(1, 4)
print('a = ', a)
b = np.linspace(1, 3, 3)
print('b = ', b)
print()
a += 1
print(a)
b -= 1
print(b)
执行结果:
a = [1 2 3]
b = [1. 2. 3.]
[2 3 4]
[0. 1. 2.]
3.4.4 通用函数
通用函数对输入数组的每个元素进行操作,生成的所有结果组成一个新的数组,输出数组的size与输入数组相同。 sqrt()、log()、sin()。
3.4.5 聚合函数
聚合函数对一组值进行操作,返回一个单一值作为结果。 sum()、min()、max()、mean()、std()。
3.5 索引、切片和迭代
3.5.1 索引
包含两种机制:正数索引(自左从0开始)、负数索引(自右从-1开始)。 一维数组程序示例:
import numpy as np
a = np.arange(1, 6)
print('a = ', a)
print(a[0])
print(a[1]) # 正数索引
print(a[-1])
print(a[-2])
执行结果:
a = [1 2 3 4 5]
1
2
5
4
二维数组程序示例:
b = np.arange(1,10).reshape((3,3))
print(b)
print(b[0][0])
print(b[1][1])
print(b[2][2])
执行结果:
[[1 2 3]
[4 5 6]
[7 8 9]]
1
5
9
3.5.2 切片
一维数组的切片 程序示例:
import numpy as np
a = np.arange(0, 9)
print('a = ', a)
print('a[1:6] = ', a[1:6]) # 元素的起始索引,开区间
# 间隔抽取
print('a[1:6:2] = ', a[1:6:2]) # 在切片中,每两个元素取一个,即每隔一个元素取一个
print()
# 间隔抽取默认值
print('a[0:6] = ', a[0:6])
print('a[:6:2] = ', a[:6:2]) # 第一个数字省略,切片默认从数组最左侧(索引为0)开始
print()
print('a[1:] = ', a[1:])
print('a[1::2] = ', a[1::2]) # 第二个数字省略,切片默认到数组最右侧结束
print()
print('a[1:6] = ', a[1:6])
print('a[1:6:] = ', a[1:6:]) # 最后一个省略,间隔默认取1
执行结果:
a = [0 1 2 3 4 5 6 7 8]
a[1:6] = [1 2 3 4 5]
a[1:6:2] = [1 3 5]
a[0:6] = [0 1 2 3 4 5]
a[:6:2] = [0 2 4]
a[1:] = [1 2 3 4 5 6 7 8]
a[1::2] = [1 3 5 7
a[1:6] = [1 2 3 4 5]
a[1:6:] = [1 2 3 4 5]
二维数组的切片 程序示例:
import numpy as np
a = np.arange(1,10).reshape((3,3))
print(a, '\n')
print(a[:, 1], '\n') # 省略第一个,默认选择所有行
print(a[1, :], '\n') # 省略第二个,默认选择所有列
print(a[0:2, 1:3], '\n') # 0到1行,1到2列
print(a[[0, 2], 1:3]) # [0,2]用列表表示,选择第0行和第2行;
执行结果
[[1 2 3]
[4 5 6]
[7 8 9]]
[2 5 8]
[4 5 6]
[[2 3]
[5 6]]
[[2 3]
[8 9]]
3.5.3 迭代
使用for循环遍历数组 程序示例:
import numpy as np
# 1 迭代一维数组
a = np.arange(1, 6)
print(a, '\n')
for item in a:
print(item)
print()
# 2 迭代二维数组
b = np.arange(1, 10).reshape((3, 3))
print(b, '\n')
print('2.1 以行为单位输出:')
for row in b:
print(row)
print('2.2 使用嵌套循环遍历每个元素:')
for row in b:
for item in row:
print(item)
print('2.3 通过一维迭代器flat遍历数组')
"""
ndarray.flat
A 1-D iterator over the array。(遍历数组的一维迭代器)
Return a copy of the array collapsed into one dimension.(flat是numpy.flatier的实例,将原数组折叠为一个一维数组,然后返回。)
"""
for item in b.flat: # 将数组b中的元素按顺序组成一个一维数组
print(item)
执行结果:
[1 2 3 4 5]
1
2
3
4
5
[[1 2 3]
[4 5 6]
[7 8 9]]
2.1 以行为单位输出:
[1 2 3]
[4 5 6]
[7 8 9]
2.2 使用嵌套循环遍历每个元素:
1
2
3
4
5
6
7
8
9
2.3 通过一维迭代器flat遍历数组
1
2
3
4
5
6
7
8
9
NumPy方法apply_along_axis() 如果想用函数处理数组的每一列或行(按整行或整列处理),可以使用优雅的NumPy方法apply_along_axis(),遍历数组。 程序示例:
import numpy as np
b = np.arange(1, 10).reshape((3, 3))
print(b, '\n')
# 聚合函数
print(np.apply_along_axis(np.mean, axis=0, arr=b)) # 对每一列求平均值
print(np.apply_along_axis(np.mean, 1, b)) # 对每一行求平均值
print()
def foo(x):
return x/2
print(np.apply_along_axis(foo, 1, b)) # 将每一行除以2
执行结果:
[[1 2 3]
[4 5 6]
[7 8 9]]
[4. 5. 6.]
[2. 5. 8.]
[[0.5 1. 1.5]
[2. 2.5 3. ]
[3.5 4. 4.5]]
3.6 处理数组的形状
拆解:ravel() —— 将多维数组变成一维数组,返回数组的视图。(不需传入参数)拉直:flatten() —— 将多维数组变成一维数组,返回真实的数组,需要分配新的内存空间。(不需传入参数)转置:transpose() 将数组进行转置。(不需传入参数)调整大小:
resize()函数,不会返回新的数组,会直接改变原数组 。(需要传入一个元组)reshape()函数,会返回新的数组,不会改变原数组。(需要传入一个元组)shape属性,直接改变原数组。(需要用一个元组给其赋值)
3.6.1 堆叠数组
水平叠加 hstack()函数 首先将待叠加的两个数组,组成一个元组,然后将整个元组作为参数传入hstack()。import numpy as np
a = np.ones(9).reshape(3, 3)
print('a = ', a, '\n')
b = np.arange(1, 10).reshape((3, 3))
print('b = ', b, '\n')
print('水平叠加 = ', np.hstack((a, b)))
执行结果:a = [[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
b = [[1 2 3]
[4 5 6]
[7 8 9]]
水平叠加 = [[1. 1. 1. 1. 2. 3.]
[1. 1. 1. 4. 5. 6.]
[1. 1. 1. 7. 8. 9.]]
垂直叠加 vstack()深度叠加 dstack()列式叠加 column_stack()行式叠加 row_stack()
3.6.2 拆分NumPy数组
横向拆分 hsplit()纵向拆分 vsplit()
import numpy as np
b = np.arange(1, 10).reshape((3, 3))
print('b = ', b, '\n')
print('横向拆分 = ', np.hsplit(b, 3)) # 即竖着下刀,那么刀的移动方向就是自左至右
print('hsplit等同于hsplit(axis = 1)',np.split(b,indices_or_sections=3,axis=1)) # split()第二个参数指示将数组拆分为几个子数组;axis指示按哪个轴进行拆分
print('纵向拆分 = ', np.vsplit(b, 3))
执行结果:
b = [[1 2 3]
[4 5 6]
[7 8 9]]
横向拆分 = [array([[1],
[4],
[7]]), array([[2],
[5],
[8]]), array([[3],
[6],
[9]])]
hsplit等同于hsplit(axis = 1) [array([[1],
[4],
[7]]), array([[2],
[5],
[8]]), array([[3],
[6],
[9]])]
纵向拆分 = [array([[1, 2, 3]]), array([[4, 5, 6]]), array([[7, 8, 9]])]
深向拆分 dsplit()
3.6.3 数组的转换
tolist() 将数组转换成Python列表astype() 将数组元素转换成指定的类型
import numpy as np
b = np.arange(1, 10).reshape((3, 3))
print('b = ', b, '\n')
print('tolist(): ', b.tolist()) # 将数组转换为Python列表
print('astype(): ', b.astype('complex')) # 将数组元素转换成指定类型
执行结果:
b = [[1 2 3]
[4 5 6]
[7 8 9]]
tolist(): [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
astype(): [[1.+0.j 2.+0.j 3.+0.j]
[4.+0.j 5.+0.j 6.+0.j]
[7.+0.j 8.+0.j 9.+0.j]]
3.7 创建数组的视图和拷贝
拷贝 copy() 申请新的内存 返回的数组与原数组无关视图 view() 返回原数组的视图 修改视图,也会修改原数组
程序示例:
import numpy as np
b = np.arange(1, 10).reshape(3, 3)
print('b = ', b)
b_copy = b.copy()
print('b_copy = ', b_copy)
b_view = b.view()
print('b_view = ', b_view, '\n')
b.flat = 0
print('b = ', b)
print('b_copy = ', b_copy)
print('b_view = ', b_view)
执行结果:
b = [[1 2 3]
[4 5 6]
[7 8 9]]
b_copy = [[1 2 3]
[4 5 6]
[7 8 9]]
b_view = [[1 2 3]
[4 5 6]
[7 8 9]]
b = [[0 0 0]
[0 0 0]
[0 0 0]]
b_copy = [[1 2 3]
[4 5 6]
[7 8 9]]
b_view = [[0 0 0]
[0 0 0]
[0 0 0]]
3.8 常用概念
向量化:NumPy内部实现循环,用户无需再实现。例如计算两个数组的乘积:A*B。(C语言中就只能用for循环计算了)广播机制:自动填充数组,以完成数组间的某些计算。
3.9 数组数据文件的读写
3.9.1 二进制文件的读写
程序示例:
import numpy as np
a = np.arange(16).reshape(4,4)
np.save('saved_data',a) # 保存到saved_data.npy文件中,扩展名.npy,扩展名系统会自动添加
print('a = ', a, '\n')
loaded_data = np.load('saved_data.npy') # 注意,在读取文件时需要自己加上扩展名
print('loaded_data = ', loaded_data)
执行结果:
a = [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
loaded_data = [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
3.9.2 读取文件中的列表形式数据
此处以读取CSV文件中数据为例,可以看出,文件中有缺失数据:
#data.csv
id,value1,value2,value3
1,123,1.4,23
2,110,,18
3,,2.1,19
程序示例:
import numpy as np
data = np.genfromtxt('data.csv', delimiter = ',', names = True)
print(data)
print(data['id']) # 将标题看成能够充当索引的标签,用它们按列抽取标签
print(data[0]) # 使用数值索引按行索取
执行结果:
[(1., 123., 1.4, 23.) (2., 110., nan, 18.) (3., nan, 2.1, 19.)]
[1. 2. 3.]
(1., 123., 1.4, 23.)