- ·上一篇内容:NumPy数组的创建函数
- ·下一篇内容:NumPy数组操作之数组转置
NumPy数组操作之修改数组形状
在实际应用过程中,人们常常需要修改已有数组的形状进行观察或计算。NumPy库中提供了大量的函数可以轻松的实现各种形状的变换。
在NumPy中常见的形状变换函数有以下几个。
序号 | 函数或属性名称 | 描述说明 |
---|---|---|
1 | numpy.reshape() | 在不改变原数组数据的情况下修改数组的形状 |
2 | numpy.ndarray.flat | 返回数组的一维迭代器 |
3 | numpy.ndarray.flatten() | 返回原数组的一个拷贝,并展开为一维数组 |
4 | numpy.ravel() | 返回原数组的一个一维视图或连续的一维数组 |
5 | numpy.pad() | 按照指定的宽度沿着数组的边填充数组 |
1. reshape()
numpy.reshape()函数是在不改变数组数据的前提下改变数组的形状。
其语法格式如下:
# < version 2.1
numpy.reshape(a, newshape, order='C')
# >= version 2.1
numpy.reshape(a, shape=None, order='C', newshape=None)
各参数的含义介绍如下:
a - 要改变其形状的数组;
newshape - 一个整数或整数元组,要修改的数组新形状,其应与数组原形状兼容。如果该参数为一个整型数,则结果为一个指定长度的一维数组。其中一个形状维可被设置为-1,在这种情况下,其值将有数组的长度和其余维度进行推断。
newshape参数在NumPy 2.1版本开始不再推荐使用,而由shape参数替代,在新版本中仍保留该参数是考虑兼容问题。
order - 可选参数,其为{'C', 'F', 'A'}中的值之一。默认值为'C'。该参数用于定义读写的顺序。该函数将以此顺序读取数组中的元素,并以此顺序放入新形状的数组中。'C' 是指使用C风格的索引顺序读/写数据元素(行序优先),该顺序意味着最后一个轴的索引变化最快,第一个轴的索引顺序变化最慢。'F' 是指按照Fortran风格的索引顺序读/写数据元素(列序优先),该顺序意味着第一个轴的索引变化最快,而最后一个轴的索引变化最慢。这里的'C'和'F'未考虑数组数据在内存中的布局情况,仅指索引的顺序。'A' 是指如果数组在内存中是Fortran连续的,则使用Fortran风格的索引顺序读/写数据元素,否则使用C风格的索引顺序。
shape - 与newshape参数的含义相同,是在NumPy新版本中添加的参数以替代老版本中的newshape参数。
下面使用例子来说明numpy.reshape()函数的具体使用过程。
import numpy as np a = np.array([[1, 2, 3], [4, 5, 6]]) print('a =') print(a) arr1 = np.reshape(a, 6) print('arr1 =', arr1) arr2 = np.reshape(a, 6, order='F') print('arr2 =', arr2) arr3 = np.reshape(a, (3,2)) print('\narr3 =\n', arr3) arr4 = np.reshape(a, (3,2), order='F') print('\narr4 =\n', arr4) arr5 = np.reshape(a, (3, -1)) print('\narr5 =\n', arr5)
输出结果形式如下:
a =
[[1 2 3]
[4 5 6]]
arr1 = [1 2 3 4 5 6]
arr2 = [1 4 2 5 3 6]
arr3 =
[[1 2]
[3 4]
[5 6]]
arr4 =
[[1 5]
[4 3]
[2 6]]
arr5 =
[[1 2]
[3 4]
[5 6]]
在上面的例子中,arr5中的-1是未指定该维度的大小,则被推定为2。
2. flat
flat是ndarray对象的一个属性,其返回数组的一维迭代器。可以使用该属性像处理一维数组那样迭代和处理多维数组。该属性并不会创建一个新数组,而是使用返回的迭代器顺序的访问原数组中的每个属性。
下面使用例子来说明该属性的具体使用方式。
import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) print('原数组:') print(arr) print('输出数组中的每个元素:') for e in arr.flat: print(e) print('将数组中的每个元素*2:') for i, e in enumerate(arr.flat): arr.flat[i] = e * 2 print(arr) print('将数组中的全部元素设置为1:') arr.flat = 1 print(arr) print('将数组的第1,2,5号元素设置为0:') arr.flat[[1, 2, 5]] = 0 print(arr)
输出结果如下:
原数组:
[[1 2 3]
[4 5 6]]
输出数组中的每个元素:
1
2
3
4
5
6
将数组中的每个元素*2:
[[ 2 4 6]
[ 8 10 12]]
将数组中的全部元素设置为1:
[[1 1 1]
[1 1 1]]
将数组的第1,2,5号元素设置为0:
[[1 0 0]
[1 1 0]]
3. flatten()
ndarray.flatten()函数是将原数组展开为一维数组,并返回该数组。该函数将创建原数组的一个一维数组。
其语法格式如下:
ndarray.flatten(order='C')
该函数仅有一个参数:
order - 可选参数,是{'C', 'F', 'A', 'K'}中的值之一。默认值为'C'。其中,'C' 是指按行优先(C风格)展开原数组。'F' 是指按列优先(Fortran风格)展开原数组。'A' 是指如果数组在内存中是Fortran连续的,则按'F'处理,否则按'C'处理。'K' 是指按元素在内存中出现的顺序进行展开。
下面举例子说明该函数的使用方式。
import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]])
print('原数组:')
print(arr)
f1 = arr.flatten()
print("展开后(order使用默认值'C'):")
print(f1)
f2 = arr.flatten('F')
print("展开后(order='F'):")
print(f2)
输出结果:
原数组:
[[1 2 3]
[4 5 6]]
展开后(order使用默认值'C'):
[1 2 3 4 5 6]
展开后(order='F'):
[1 4 2 5 3 6]
4. ravel()
numpy.ravel()函数将原数组处理为一个一维数组。该函数与flatten()函数相比,numpy.ravel()函数返回原数组扁平化视图,只有在原数组非连续存储时才会返回一个副本。而flatten()函数返回的是原数组数据的一个副本。
同时,需要注意,flatten()是ndarray对象的一个函数,而ravel()是NumPy模块提供的一个基本函数,两者的调用方式不相同。
其语法格式如下:
numpy.ravel(a, order='C')
其两个参数的含义描述如下:
a - 输入的原数组。该数组的元素以order参数指定的顺序被读取,并被打包成一个一维数组。
order - 可选参数,其值为{'C', 'F', 'A', 'K'}中的之一。其默认值为'C'。表示读取数组a中元素的顺序。'C' 表示C风格的索引顺序(行优先),其最后一个轴索引的顺序变化最快,而第一个轴索引的顺序变化最慢。'F'表示Fortran风格的索引顺序(列优先),其第一个轴索引顺序变化最快,而最后一个轴索引顺序变化最慢。'C' 和 'F' 不考虑底层数组在内存中存储的顺序,仅指轴索引的顺序。'A'表示输入的数组a如果在内存中是Fortran连续的,则按'F'来处理,否则按'C'来处理。'K' 表示按元素在内存中的实际顺序进行读取。
下面使用例子来说明numpy.ravel()函数的使用方式。
import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]])
print('原数组:')
print(arr)
r1 = np.ravel(arr)
print("order使用默认值'C':")
print(r1)
r2 = np.ravel(arr, 'F')
print("order='F':")
print(r2) print('修改索引2处的值为100:')
r1[2]=100
print('r1 =', r1)
print('原数组为:\n', arr)
输出结果如下:
原数组:
[[1 2 3]
[4 5 6]]
order使用默认值'C':
[1 2 3 4 5 6]
order='F':
[1 4 2 5 3 6]
修改索引2处的值为100:
r1 = [ 1 2 100 4 5 6]
原数组为:
[[ 1 2 100]
[ 4 5 6]]
5. pad()
numpy.pad()函数用于沿着数组的边填充值。填充将会增加数组的大小,该函数可以指定填充宽度、填充模式等。
其语法格式如下:
numpy.pad(array, pad_width, mode='constant', **kwargs)
该函数的参数描述如下:
array - 用于被填充的数组。
pad_width - 每个轴填充的宽度,其值可以是一个整数、元组或元组的序列。
mode - 可选参数,用于设定填充的方式。其值为一个字符串或一个用户定义的函数。其可选的字符串包括:
'constant':(默认值),以常量值填充
'edge': 使用数组的边缘值填充
'linear_ramp': 使用end_value和边缘值线性递减的方式填充,end_value默认为0
'maximum': 使用全部值的最大值或当前轴的最大值进行填充
'mean': 使用全部值的平均值或当前轴的平均值进行填充
'median': 使用全部值的中值或当前轴的中值进行填充
'minimum': 使用全部值的最小值或当前轴的最小值进行填充
'reflect': 反射填充,轴后边的值填充到前端,轴前端的值填充到后边;填充时不含边界值
'symmetric': 对称填充
'wrap': 环绕填充,在轴的方向上用前边的值填充后端,而后端的值使用开头的值进行填充
'empty': 使用未定义的值进行填充。
kwargs - 附加的关键字参数,其依据参数mode设置的不同值,其提供的参数类别不同。
主要包括:
stat_length : 用于mode参数设置为'maximum','mean','median'和'minimum'时,指定每个轴上参与统计值计算的边缘值。默认值为None,指使用整个轴。
constant_values : 用于mode参数设置为'constant'时,指定每个轴上用于填充的值。默认值为0。
end_values : 用于mode参数设置为'linear_ramp'时,指定linear_ramp的终值。
reflect_type : {'even', 'odd'}值之一。用于mode参数设置为'reflect'及'symmetric'时指定反射的类型。默认为'even',则边缘值两侧的值是对称的。若为'odd',则边缘值右侧的每个值与边缘值的差等于边缘值与左侧对应值的差。
下面使用例子来说明numpy.pad()函数的使用方式。
import numpy as np a = [1, 2, 3, 4, 5]
print('constant,pad_width=(2,3),constant_values=(4,6):')
print(np.pad(a, (2, 3), 'constant', constant_values=(4, 6)))
print('edge, pad_width=(2,3):')
print(np.pad(a, (2, 3), 'edge'))
print('linear_ramp,end_values=(5,-4):')
print(np.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4)))
print('maximum,pad_width=2:')
print(np.pad(a, (2,), 'maximum'))
print('mean,pad_width=2:')
print(np.pad(a, (2,), 'mean'))
print('median,pad_width=2:')
print(np.pad(a, (2,), 'median'))
print('minimum,padwidth=((3,2),(2,3)):')
b = [[1, 2], [3, 4]]
print(np.pad(b, ((3, 2), (2, 3)), 'minimum'))
print('reflect:')
print(np.pad(a, (2, 3), 'reflect'))
print("reflect,reflect_type='odd'")
print(np.pad(a, (2, 3), 'reflect', reflect_type='odd'))
print('symmetric:')
print(np.pad(a, (2, 3), 'symmetric'))
print("symmetric,reflect_type='odd'")
print(np.pad(a, (2, 3), 'symmetric', reflect_type='odd'))
print('wrap:')
print(np.pad(a, (2, 3), 'wrap'))
输出结果如下所示:
constant,pad_width=(2,3),constant_values=(4,6):
[4 4 1 2 3 4 5 6 6 6]
edge, pad_width=(2,3):
[1 1 1 2 3 4 5 5 5 5]
linear_ramp,end_values=(5,-4):
[ 5 3 1 2 3 4 5 2 -1 -4]
maximum,pad_width=2:
[5 5 1 2 3 4 5 5 5]
mean,pad_width=2:
[3 3 1 2 3 4 5 3 3]
median,pad_width=2:
[3 3 1 2 3 4 5 3 3]
minimum,padwidth=((3,2),(2,3)):
[[1 1 1 2 1 1 1]
[1 1 1 2 1 1 1]
[1 1 1 2 1 1 1]
[1 1 1 2 1 1 1]
[3 3 3 4 3 3 3]
[1 1 1 2 1 1 1]
[1 1 1 2 1 1 1]]
reflect:
[3 2 1 2 3 4 5 4 3 2]
reflect,reflect_type='odd'
[-1 0 1 2 3 4 5 6 7 8]
symmetric:
[2 1 1 2 3 4 5 5 4 3]
symmetric,reflect_type='odd'
[0 1 1 2 3 4 5 5 6 7]
wrap:
[4 5 1 2 3 4 5 1 2 3]
微信搜索“优雅的代码”关注本站的公众号,或直接使用微信扫描下面二维码关注本站公众号,以获取最新内容。
个人成长离不开各位的关注,你的关注就是我继续前行的动力。