【完】Numpy学习笔记

【numpy笔记_8】array对象的拼接、分割

2023-02-27  本文已影响0人  fakeProgramer

像上篇最后说的,“轴”概念是numpy中很重要的概念。对一个ndarray来说,轴用0,1,2,...,n-1表示。

轴既代表数组颗粒度的大小,从0轴到n轴颗粒度递增,即数组单位越来越小。
同时,“轴”又可以理解为对ndarray的shape(1,2,3,...,n)的索引,0轴指向了1。

回顾完轴的概念,我们开始今天的学习。
拼接与分割都是调用不同的方法。

拼接

拼接数组和序列,浅记一下:

方法 描述 常用的参数
np.concatenate() (数组)拼接在指定轴之后 多个数组的元组
axis: 指定拼接的轴
np.stack() (数组)拼接在新轴之后 多个数组的元组
axis: 指定的基准轴,用于调整拼接的颗粒度
np.hstack() (数组)拼接在行上(水平拼接) /
np.vstack() (数组)拼接在列上(垂直拼接) /

np.concatenate()方法:(数组)拼接在指定轴之后

import numpy as np
arr1 = np.arange(12).reshape(3,4)
arr2 = np.ones(12).reshape(3,4)
concatenate_it_axis0 = np.concatenate((arr1,arr2), axis=0)  # 指定在0轴上拼接,即行延续
concatenate_it_axis1 = np.concatenate((arr1,arr2), axis=1)  # 指定在1轴上拼接,即列延续
print('concatenate_it_axis0的拼接效果:\n', concatenate_it_axis0)
print('concatenate_it_axis1的拼接效果:\n', concatenate_it_axis1)
# 运行结果:
concatenate_it_axis0的拼接效果:
[[ 0.  1.  2.  3.]
 [ 4.  5.  6.  7.]
 [ 8.  9. 10. 11.]
 [ 1.  1.  1.  1.]
 [ 1.  1.  1.  1.]
 [ 1.  1.  1.  1.]]
concatenate_it_axis1的拼接效果:
[[ 0.  1.  2.  3.  1.  1.  1.  1.]
 [ 4.  5.  6.  7.  1.  1.  1.  1.]
 [ 8.  9. 10. 11.  1.  1.  1.  1.]]

np.stack()方法:(数组)拼接在新轴之后

这个方法抽象一点。我们试着理解一下:
由于stack()方法是增加新轴,所以对于一个shape(b,a)而言,新数组的shape其实为(c,b,a)
axis参数的书写标准也在于此,用以指定数据拼接时的颗粒度大小,即对于shape(b,a):

axis=0:增加新轴,块块拼接(直接以增加新轴的方式对两个数组拼接)
axis=1:增加新轴,行行拼接
axis=2:增加新轴,列列拼接

思考一下,如果是拼接两个数组的shape(c,b,a),axis怎么写呢?
没错,stack()后的数组,其shape就变成了(d,c,b,a),所以axis的效果就像这样:

axis=0:增加新轴,大块进行拼接(也相当于两个数组直接拼接)
axis=1:增加新轴,块块拼接
axis=2:增加新轴,行行拼接
axis=3:增加新轴,列列拼接

是的,其实不难理解。

结合例子看下:

import numpy as np
arr1 = np.arange(12).reshape(3,4)
arr2 = np.ones(12).reshape(3,4)
atack_it_axis2 = np.stack((arr1,arr2), axis=2)  # 增加新轴,列列拼接
atack_it_axis0 = np.stack((arr1,arr2), axis=0)  # 增加新轴,直接拼接
atack_it_axis1 = np.stack((arr1,arr2), axis=1)  # 增加新轴,行行拼接

print('atack_it_axis2,增加新轴的拼接数组:\n',atack_it_axis2)
print('atack_it_axis0,增加新轴的拼接数组:\n',atack_it_axis0)
print('atack_it_axis1,增加新轴的拼接数组:\n',atack_it_axis1)
# 运行结果:
atack_it_axis2,增加新轴的拼接数组:
 [[[ 0.  1.]
  [ 1.  1.]
  [ 2.  1.]
  [ 3.  1.]]

 [[ 4.  1.]
  [ 5.  1.]
  [ 6.  1.]
  [ 7.  1.]]

 [[ 8.  1.]
  [ 9.  1.]
  [10.  1.]
  [11.  1.]]]
atack_it_axis0,增加新轴的拼接数组:
 [[[ 0.  1.  2.  3.]
  [ 4.  5.  6.  7.]
  [ 8.  9. 10. 11.]]

 [[ 1.  1.  1.  1.]
  [ 1.  1.  1.  1.]
  [ 1.  1.  1.  1.]]]
atack_it_axis1,增加新轴的拼接数组:
 [[[ 0.  1.  2.  3.]
  [ 1.  1.  1.  1.]]

 [[ 4.  5.  6.  7.]
  [ 1.  1.  1.  1.]]

 [[ 8.  9. 10. 11.]
  [ 1.  1.  1.  1.]]]
无论是np.concatenate()还是np.stack(),拼接一个数组,要求两个拼接的对象的维度要相同。

这很好理解,因为不同维度的错误拼接就像这张图一样:


维度错误的数组拼接.png
np.hstack()水平拼接(延续列)和np.vstack()垂直拼接(延续行)就没什么好讲的,直接传入数组就行。np.concatenate()方法同样能完成这些操作。

分割

方法 描述 常用的参数
np.split() 沿指定轴切分 ary: 要分割的数组;
axis: 指定分割的轴
np.hsplit() (数组)按轴水平分割 ary: 要分割的数组;
axis: 指定分割的轴
np.vsplit() (数组)按轴垂直分割 ary: 要分割的数组;
axis: 指定分割的轴

用一个例子看看np.split()的操作,其他的用法类似就不多讲了:

import numpy as np
arr1 = np.arange(16).reshape(4,4)
res1, res2 = np.split(arr1, 2)  # 平均2等分,按行(axis不写默认=0)
print('arr1:\n', arr1)
print('arr1切开前半段:\n', res1)
print('arr1切开后半段:\n', res2)
# 运行结果:
arr1:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
arr1切开前半段:
 [[0 1 2 3]
 [4 5 6 7]]
arr1切开后半段:
 [[ 8  9 10 11]
 [12 13 14 15]]

arr1 = np.arange(16).reshape(4,4)
res1, res2 = np.split(arr1, 2, axis=1)  # 平均2等分,按列
print('arr1:\n', arr1)
print('arr1切开前半段:\n', res1)
print('arr1切开后半段:\n', res2)
# 运行结果:
arr1:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
arr1切开前半段:
 [[ 0  1]
 [ 4  5]
 [ 8  9]
 [12 13]]
arr1切开后半段:
 [[ 2  3]
 [ 6  7]
 [10 11]
 [14 15]]

arr1 = np.arange(16).reshape(4,4)
res1, res2 = np.split(arr1, 3)  # 平均3等分。分不成三块,报错
print('arr1:\n', arr1)
print('arr1切开前半段:\n', res1)
print('arr1切开后半段:\n', res2)
# 运行结果:
报错

arr1 = np.arange(16).reshape(4,4)
res1, res2 = np.split(arr1, [1])  # 切第一行与后面几行
print('arr1:\n', arr1)
print('arr1切开前半段:\n', res1)
print('arr1切开后半段:\n', res2)
# 运行结果:
arr1:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
arr1切开前半段:
 [[0 1 2 3]]
arr1切开后半段:
 [[ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]

arr2 = np.arange(12)
res1, res2 = np.split(arr2, indices_or_sections=[3])  # 按元素切。指定的元素在后面数组的第一位
print('arr1:\n', arr2)
print('arr1切开前半段:\n', res1)
print('arr1切开后半段:\n', res2)
# 运行结果:
arr1:
 [ 0  1  2  3  4  5  6  7  8  9 10 11]
arr1切开前半段:
 [0 1 2]
arr1切开后半段:
 [ 3  4  5  6  7  8  9 10 11]

上一篇 下一篇

猜你喜欢

热点阅读