NumPy核心数据结构:ndarray
- NumPy的数组类被称作ndarray。通常被称作数组。注意numpy.array和标准Python库类array.array并不相同,后者只处理一维数组和提供少量功能。
- 一种由相同类型的元素组成的多维数组,元素数量是事先给定好的。
- 元素的数据类型由dtype对象来指定,每个ndarray只有一种dtype类型。
- ndarray的大小固定,创建好数组后大小是不会再发生改变的。
ndarray创建
可以通过numpy模块中的常用的几个函数进行创建ndarray多维数组对象,主要函数如下:
array函数
接收一个普通的python序列,并将其转换为ndarray。
#用一维列表创建
np.array([1,2,3])
#用元组创建
np.array((1,2,3))
#多维数组
np.array([
[1,2,3,4]
[5,6,7,8]
])
np.array([
[
[1,2,3],
[4,5,6]
],
[
[7,8,9],
[10,11,12]
]
])
zeros函数
创建指定长度或者形状的全零数组。
#通过zeros创建数组 创建一个元素为零的数组
np.zeros((3,3)) #3×3的二维数组
np.zeros((2,3,4)) #2×3×3的三维数组
ones函数
创建指定长度或者形状的全1数组。
#ones 生成元素为1的数组。
np.ones((3,3)) #3×3的二维数组
empty函数
创建一个没有任何具体值的数组(准确地说是创建一些未初始化的ndarray多维数组)。
np.empty((3,3)) #3×3的二维数组
ndarray其它创建方式
arange函数
类似python的range函数,通过指定开始值、终止值和步长来创建一个一维数组。注意:最终创建的数组不包含终止值。
#arange
np.arange(1,9,2) #[1,3,5,7] 步长为2
np.arange(9,1,-1) #[9,8,7,6,5,4,3,2] 步长为-1
linspace函数
通过指定开始值、终止值和元素个数来创建一个一维数组,数组的数据元素符合等差数列。可以通过endpoint关键字指定是否包含终止值,默认包含终止值。
#linspace生成等差数列
np.linspace(1,10,5)
#[1,3.25,5.5,7.75,10] 共计5个元素以等差数列排列在1到10之间
logspace函数
和linspace函数类似,不过创建的是等比数列。
np.logspace(0,2,5)
#共计5个元素以等比数列排列在10^0和10^2之间。
np.logspace(0,2,5,base=2)
#共计5个元素以等比数列排列在2^0和2^2之间。
使用随机数填充数组
使用numpy.random中的random()函数来创建0-1之间的随机元素,数组包含的元素数量由参数决定。
np.random.random((3,3)) #随机初始化3×3的二维数组。
ndarray对象属性
ndim
数组轴的个数,轴的个数被称作秩。
a = np.array([
[1,2,3],
[4,5,6],
[7,8,9]
])
print(“维度的数量:”,a.ndim) #维度的数量是:2
shape
a = np.array([
[1,2,3],
[4,5,6],
[7,8,9]
])
print(“数组的形状:”,a.shape) #数组的形状是(3,3)
dtype
a = np.array([
[1,2,3],
[4,5,6],
[7,8,9]
])
print(“数组的元素类型:”,a.dtype) #数组的元素类型:int32
size
a = np.array([
[1,2,3],
[4,5,6],
[7,8,9]
])
print(“数组的元素数量:”,a.size) #数组的元素数量:9
itemsize
数组中每个元素的字节大小。例如,一个元素类型为float64的数组itemsiz属性值为8,即64/8 = 8。又如,一个元素类型为complex32的数组item属性为4,即32/8 = 4。
ndarray中元素数据类型
创建numpy数组的时候可以通过属性dtype显示指定数据类型,如果不指定的情况下,numpy会自动推断出适合的数据类型,所以一般不需要显示给定数据类型。
如果需要更改一个已经存在的数据的数据类型,可以通过astype方法进行修改从而得到一个新数组。
a = np.array([1,2,3,4])
print(a.dtype) #int32
b = np.astype(float)
print(a.dtype) #int32
print(b.dtype) #float64
ndarray修改形状
对于一个已经存在的ndarray数组对象而言,可以通过修改形状相关的参数/方法从而改变数组的形状。
- 直接修改数组ndarray的shape值。
- 直接使用reshape函数创建一个改变尺寸的新数组,原数组的shape保持不变,但是新数组和原数组共享一个内存空间,也就是修改任何一个数组中的值都会对另一个产生影响,另外要求新数组的元素个数和原数组一样。
当指定某一个轴为-1的时候,表示将根据数组元素的数量自动计算该轴的长度。
#shape修改
arr = np.random.randint(1,9,size(2,5))
arr,shape = (5,2)
#reshape
arr = np.arange(9)
#array([0,1,2,3,4,5,6,7,8])
arr_new = arr.reshape(3,3)
#array([[0,1,2],
# [3,4,5],
# [6,7,8]])
#推荐写法
arr = np.arange(9).reshape(3,3)
ndarray-数组与标量、数组之间的运算
- 数组不用循环即可对每个元素执行批量的算术运算操作,这个过程叫做矢量化,即用数组表达式代替循环的做法。
- 矢量化数组运算性能比纯Python方式快上一两个数据级。
- 大小相等的两个数组之间的任何算术运算都会将其运算应用到元素级上的操作。
- 元素级操作:在NumPy中,大小相等的数据之间的运算称为元素级运算,即只用于位置相同的元素之间,所得的运算结果组成一个新的数组,运算结果的位置跟操作数的位置相同。
arr1 = np.array([
[10,20,30],
[40,50,60]
])
arr2 = np.array([
[1,2,3],
[4,5,6]
])
print(arr1 + arr2)
#array([
# [11,22,33]
# [44,55,66]
#])
print(arr1 – arr1)
#array([
# [9 ,18,27]
# [36,45,54]
#])
print(arr1 * arr2)
#array([
# [10 ,40 ,90 ]
# [160,250,360]
#])
print(arr1 / arr2)
#array([
# [10,10,10]
# [10,10,10]
#])
np.dot(arr1,arr2) #点乘运算
ndarray-多维数组的索引
#常规写法
print(arr[0][0][1])
#推荐写法
print(arr[0,0,1])
ndarray-数组的切片
在各维度上单独切片,如果某维度都保留,则直接使用:冒号,不指定起始值和终止值。
np.array([[[6,3,6],
[4,4,6],
[5,8,7]],
[[4,3,2],
[6,1,4],
[6,3,6]])
print(arr[:,:,1])
#[[3 4 8]
#[3 1 3]]
np.array([[[3,1,4,3],
[4,5,2,3],
[8,2,2,8]],
[[4,3,7,4],
[4,2,1,7],
[8,1,1,6]])
print(arr[0,0:3:2,1:3])
#[[1 4]
#[2 2]]
ndarray-花式索引
花式索引(Fancy indexing)指的是利用整数数组进行索引的方式。
arr = np.arange(32).reshape(8,4)
#获取第0、3、5行的数据
print(arr[0,3,5])
#获取第(0,0)、(3,3)、(5,2)这三个索引位置的数据
print(arr[[0,3,5],[0,3,2]])
#获取第0、3、5行的0、2、3列的数据
#ix_函数会产生一个索引器
print(arr[np.ix_([0,3,5],[0,2,3])])
ndarray-布尔类型索引
利用布尔类型的数据进行数据索引,最终返回的结果是对应索引数组中数据为True位置的值。
ndarray-聚合函数
聚合函数是对一个数组进行操作,并返回一个单一值作为结果的函数。当然聚合函数也可以指定对某个具体的轴进行数据聚合操作。常用的聚合操作有求平均值、最大值、最小值、标准差等等。
arr = np.array([[1,2,3,4],[7,8,9,10]])
print(“min=”,arr.min())
print(“max=”,arr.max())
print(“mean=”,arr.mean())
print(“std=”,arr.std())
#二维数组的情况下,axis=0表示对同列的数据进行聚合;axis=1表示对同#行的数据进行聚合。
print(“min=”,arr.min(axis=0))
print(“max=”,arr.max(axis=0))
print(“mean=”,arr.mean(axis=1))
print(“std=”,arr.std(axis=1))
ndarray-数组转置与轴对换
数组转置是指将shape进行重置操作,并将其值重置为原始shape元组的倒置,比如原始的shape值为(2,3,4),那么转置后的新元组的shape值为(4,3,2)。
对于二维数组而言(矩阵)数组的转置其实就是矩阵的转置。
可以通过调用数组的transpose函数或者T属性进行数组转置操作。
arr = np.arange(40).reshape(5,-1)
arr1 = arr.transpose()
arr2 = arr.T
np.where函数
np.where函数是三元表达式x if condition else y的矢量化版本。
#[[True,False],[True,True]]为条件表达式
#[[1,2],[3,4]]条件为真时的值
#[[9,8],[7,6]]条件为假时的值
np.where([[True,False],[True,True]],[[1,2],[3,4]],[[9,8],[7,6]])
#array([[1,8],
# [3,4]])
arr1 = np.random.randint(1,9,size=(3,3))
arr2 = np.random.randint(1,9,size=(3,3))
condition = arr1 < arr2
arr3 = np.where(condition,arr1,arr2)
案例:将数组中的所有异常数字替换为0
arr = np.array([
[1,2,3,np.NaN],
[1,2,3,np.ni],
[1,2,3,np.e]
])
condition = np.isnan(arr)|np.isinf(arr)
arr2 = np.where(condition,0,arr)
np.unique函数
np.unique函数的主要作用是将数组中的元素进行去重操作(也就是只保存不重复的数据)
arr = np.array([‘a’, ‘b’, ‘c’, ‘d’, ‘a’, ‘c’])
arr2 = np.unique(arr)