NumPy之操控ndarray的形状

系列文章

一次性搞定NumPy入门基础知识
NumPy之操控ndarray的形状
NumPy之浅拷贝和深拷贝
NumPy之索引技巧

概述

这里主要总结针对ndarray形状的三种操作:

  • 改变ndarray的形状
  • 堆叠几个ndarray
  • 拆分ndarray

改变ndarray的形状

以下列ndarray为例:

>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 2.,  8.,  0.,  6.],
       [ 4.,  5.,  1.,  1.],
       [ 8.,  9.,  3.,  6.]])
>>> a.shape
(3, 4)    

如下三个是改变ndarray形状的三个常用命令,注意这三个命令并不改变原始的ndarray:

>>> a.ravel()  # 将原始ndarray转化为一维ndarray并返回
array([ 2.,  8.,  0.,  6.,  4.,  5.,  1.,  1.,  8.,  9.,  3.,  6.])

>>> a.reshape(6,2)  # 指定新的shape,返回不同shape的ndarray
array([[ 2.,  8.],
       [ 0.,  6.],
       [ 4.,  5.],
       [ 1.,  1.],
       [ 8.,  9.],
       [ 3.,  6.]])

>>> a.T  # 返回转置后的ndarray,类似于线性代数中的转置矩阵
array([[ 2.,  4.,  8.],
       [ 8.,  5.,  9.],
       [ 0.,  1.,  3.],
       [ 6.,  1.,  6.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)  

注意,上述的几个命令,改变形状时遵循的原则都是“C-style”的。也就是说,最右边的索引,变化的最快。以a.ravel()为例,在改变形状时,a[0][0]之后紧跟的元素是a[0][1]。NumPy的内部存储也是遵循这种顺序,因此,使用ravel()并不会导致拷贝的操作。当然,ravel()reshape()都可以通过参数来进行控制,改变成例如采用"FORTRAN-style"的模式,使得最左边的索引变得最快。

注意下面两个方法的区别:reshape返回一个新的ndarray,而resize则会直接修改这个ndarray本身。

>>> a
array([[ 2.,  8.,  0.,  6.],
       [ 4.,  5.,  1.,  1.],
       [ 8.,  9.,  3.,  6.]])
>>> a.resize((2,6))
>>> a
array([[ 2.,  8.,  0.,  6.,  4.,  5.],
       [ 1.,  1.,  8.,  9.,  3.,  6.]]) 

如果reshape的某一个参数是-1,那么reshape的最终形状将会由函数自动计算出来。

>>> a.reshape(3,-1)
array([[ 2.,  8.,  0.,  6.],
       [ 4.,  5.,  1.,  1.],
       [ 8.,  9.,  3.,  6.]]) 

ndarray的堆叠

几个不同的ndarray可以沿着指定的axis进行堆叠,举例如下:

>>> a = np.floor(10*np.random.random((2,2)))
>>> a
array([[ 8.,  8.],
       [ 0.,  0.]])
>>> b = np.floor(10*np.random.random((2,2)))
>>> b
array([[ 1.,  8.],
       [ 0.,  4.]])

>>> np.vstack((a,b))
array([[ 8.,  8.],
       [ 0.,  0.],
       [ 1.,  8.],
       [ 0.,  4.]])

>>> np.hstack((a,b))
array([[ 8.,  8.,  1.,  8.],
       [ 0.,  0.,  0.,  4.]])    

上例以二维ndarray为例,vstack方法沿着垂直的方向堆叠(也就是第一个axis),hstack方法沿着水平方向堆叠(也就是第二个axis)。

需要注意column_stack方法,对于两个1D的ndarray,它会把它们堆叠成一个2D的ndarray。例如:

>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6])
>>> np.column_stack((a,b))
array([[1, 4],
       [2, 5],
       [3, 6]])

对于2D的ndarray来说,column_stack的作用等同于hstack,否则hstack会把两个1D的ndarray当作行来进行合并:

>>> from numpy import newaxis
>>> a = np.floor(10*np.random.random((2,2)))
>>> b = np.floor(10*np.random.random((2,2)))
>>> np.column_stack((a,b))    
array([[ 8.,  8.,  1.,  8.],
       [ 0.,  0.,  0.,  4.]])
>>> a = np.array([4.,2.])
>>> b = np.array([3.,8.])
>>> np.column_stack((a,b))     
array([[ 4., 3.],
       [ 2., 8.]])
>>> np.hstack((a,b))           # 结果不同,这时hstack把两个1D ndarray当作行向量来处理了
array([ 4., 2., 3., 8.])
>>> a[:,newaxis]               # 变换axis
array([[ 4.],
       [ 2.]])
>>> np.column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4.,  3.],
       [ 2.,  8.]])
>>> np.hstack((a[:,newaxis],b[:,newaxis]))   # 这时候结果一致了
array([[ 4.,  3.],
       [ 2.,  8.]])  

另一方面,row_stack在任何时候和vstack都是等同的。总结一下,对于两维以上的ndarray,hstack沿着第二个axis合并,vstack沿着第一个axis合并,concatenate则通过参数控制,来决定沿着哪个方向进行合并。

另外,在一些复杂的场景,可以使用r_c_来创建ndarray,举例如下:

>>> np.r_[1:4,0,4]
array([1, 2, 3, 0, 4])

其中的:和arange方法中的意义相同。在这里,r_c_的作用分别类似于vstackhstack的作用,但也允许通过参数控制来决定沿着哪个axis进行堆叠。

需要注意,沿着某一个axis进行堆叠时,参与堆叠的ndarray的其他axis的length必须相同。
例如一个3 \times 2的ndarray可以和另一个5 \times 2的ndarray沿着第一个axis进行堆叠,但却不能和另一个3 \times 3的ndarray沿着第一个axis进行堆叠。

ndarray的拆分

一个ndarray可以拆分成几个小的ndarray。这里以hsplit为例,该函数可以沿着水平方向拆分ndarray。可以以两种方式给其传参。一种是,指定参数N,说明将原始ndarray拆分成几个小的ndarray,NumPy会根据这个参数,沿着这个方向将原来的ndarray等分成N份(如果列数不能被N整除,将会报错);另一种是,指定在哪些列后面切一刀,NumPy会根据这个指示,将原始的ndarray进行拆分。

举例,对于一个6列的ndarray,如果传入参数3,那么NumPy将会按如下方式,将这个ndarray进行等分:
\begin{array}{cc:cc:cc} a_{00} & a_{01} & a_{02} & a_{03} & a_{04} & a_{05} \\ a_{10} & a_{11} & a_{12} & a_{13} & a_{14} & a_{15} \end{array}
同样的ndarray,如果传入参数(1,3),那么NumPy会在对应的列后面划一条线(第一列后面、第三列后面),进行分拆:
\begin{array}{c:cc:ccc} a_{00} & a_{01} & a_{02} & a_{03} & a_{04} & a_{05} \\ a_{10} & a_{11} & a_{12} & a_{13} & a_{14} & a_{15} \end{array}

代码示例如下:

>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9.,  5.,  6.,  3.,  6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 1.,  4.,  9.,  2.,  2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])
>>> np.hsplit(a,3)   # Split a into 3
[array([[ 9.,  5.,  6.,  3.],
       [ 1.,  4.,  9.,  2.]]), array([[ 6.,  8.,  0.,  7.],
       [ 2.,  1.,  0.,  6.]]), array([[ 9.,  7.,  2.,  7.],
       [ 2.,  2.,  4.,  0.]])]
>>> np.hsplit(a,(3,4))   # Split a after the third and the fourth column
[array([[ 9.,  5.,  6.],
       [ 1.,  4.,  9.]]), array([[ 3.],
       [ 2.]]), array([[ 6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])]     
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358