感觉numpy.hstack()和numpy.column_stack()函数略有相似,numpy.vstack()与numpy.row_stack()函数也是挺像的。
stackoverflow上也有类似的讨论,在这里numpy vstack vs. column_stack。
给一个相关函数的列表:
stack() Join a sequence of arrays along a new axis.
hstack() Stack arrays in sequence horizontally (column wise).
dstack() Stack arrays in sequence depth wise (along third dimension).
concatenate() Join a sequence of arrays along an existing axis.
vsplit () Split array into a list of multiple sub-arrays vertically.
一、numpy.stack()函数
函数原型:numpy.stack(arrays, axis=0)
程序实例:
-
>>> arrays = [np.random.randn(
3,
4)
for _
in range(
10)]
-
>>> np.stack(arrays, axis=
0).shape
-
(
10,
3,
4)
-
-
>>>
-
-
>>> np.stack(arrays, axis=
1).shape
-
(
3,
10,
4)
-
-
>>>
-
-
>>> np.stack(arrays, axis=
2).shape
-
(
3,
4,
10)
-
-
>>>
-
-
>>> a = np.array([
1,
2,
3])
-
>>> b = np.array([
2,
3,
4])
-
>>> np.stack((a, b))
-
array([[
1,
2,
3],
-
[
2,
3,
4]])
-
-
>>>
-
-
>>> np.stack((a, b), axis=
-1)
-
array([[
1,
2],
-
[
2,
3],
-
[
3,
4]])
-
二、numpy.hstack()函数
函数原型:numpy.hstack(tup)
其中tup是arrays序列,The arrays must have the same shape, except in the dimensioncorresponding to axis (the first, by default).
等价于:np.concatenate(tup, axis=1)
程序实例:
-
>>> a = np.array((
1,
2,
3))
-
>>> b = np.array((
2,
3,
4))
-
>>> np.hstack((a,b))
-
array([
1,
2,
3,
2,
3,
4])
-
>>> a = np.array([[
1],[
2],[
3]])
-
>>> b = np.array([[
2],[
3],[
4]])
-
>>> np.hstack((a,b))
-
array([[
1,
2],
-
[
2,
3],
-
[
3,
4]])
三、numpy.vstack()函数
函数原型:numpy.vstack(tup)
等价于:np.concatenate(tup, axis=0) if tup contains arrays thatare at least 2-dimensional.
程序实例:
-
>>> a = np.array([
1,
2,
3])
-
>>> b = np.array([
2,
3,
4])
-
>>> np.vstack((a,b))
-
array([[
1,
2,
3],
-
[
2,
3,
4]])
-
-
>>>
-
-
>>> a = np.array([[
1], [
2], [
3]])
-
>>> b = np.array([[
2], [
3], [
4]])
-
>>> np.vstack((a,b))
-
array([[
1],
-
[
2],
-
[
3],
-
[
2],
-
[
3],
-
[
4]])
-
四、numpy.dstack()函数
函数原型:numpy.dstack(tup)
等价于:np.concatenate(tup, axis=2)
程序实例:
-
>>> a = np.array((
1,
2,
3))
-
>>> b = np.array((
2,
3,
4))
-
>>> np.dstack((a,b))
-
array([[[
1,
2],
-
[
2,
3],
-
[
3,
4]]])
-
-
>>>
-
-
>>> a = np.array([[
1],[
2],[
3]])
-
>>> b = np.array([[
2],[
3],[
4]])
-
>>> np.dstack((a,b))
-
array([[[
1,
2]],
-
[[
2,
3]],
-
[[
3,
4]]])
-
五、numpy.concatenate()函数
函数原型:numpy.concatenate((a1, a2, …), axis=0)
程序实例:
-
>>> a = np.array([[
1,
2], [
3,
4]])
-
>>> b = np.array([[
5,
6]])
-
>>> np.concatenate((a, b), axis=
0)
-
array([[
1,
2],
-
[
3,
4],
-
[
5,
6]])
-
>>> np.concatenate((a, b.T), axis=
1)
-
array([[
1,
2,
5],
-
[
3,
4,
6]])
-
-
This function will
not preserve masking of MaskedArray inputs.
-
>>>
-
-
>>> a = np.ma.arange(
3)
-
>>> a[
1] = np.ma.masked
-
>>> b = np.arange(
2,
5)
-
>>> a
-
masked_array(data = [
0 --
2],
-
mask = [
False
True
False],
-
fill_value =
999999)
-
>>> b
-
array([
2,
3,
4])
-
>>> np.concatenate([a, b])
-
masked_array(data = [
0
1
2
2
3
4],
-
mask =
False,
-
fill_value =
999999)
-
>>> np.ma.concatenate([a, b])
-
masked_array(data = [
0 --
2
2
3
4],
-
mask = [
False
True
False
False
False
False],
-
fill_value =
999999)
-
六、numpy.vsplit()函数
函数原型:numpy.vsplit(ary, indices_or_sections)
程序实例:
-
>>> x = np.arange(
16.0).reshape(
4,
4)
-
>>> x
-
array([[
0.,
1.,
2.,
3.],
-
[
4.,
5.,
6.,
7.],
-
[
8.,
9.,
10.,
11.],
-
[
12.,
13.,
14.,
15.]])
-
>>> np.vsplit(x,
2)
-
[array([[
0.,
1.,
2.,
3.],
-
[
4.,
5.,
6.,
7.]]),
-
array([[
8.,
9.,
10.,
11.],
-
[
12.,
13.,
14.,
15.]])]
-
>>> np.vsplit(x, np.array([
3,
6]))
-
[array([[
0.,
1.,
2.,
3.],
-
[
4.,
5.,
6.,
7.],
-
[
8.,
9.,
10.,
11.]]),
-
array([[
12.,
13.,
14.,
15.]]),
-
array([], dtype=float64)]
-
-
With a higher dimensional array the split
is still along the first axis.
-
>>>
-
-
>>> x = np.arange(
8.0).reshape(
2,
2,
2)
-
>>> x
-
array([[[
0.,
1.],
-
[
2.,
3.]],
-
[[
4.,
5.],
-
[
6.,
7.]]])
-
>>> np.vsplit(x,
2)
-
[array([[[
0.,
1.],
-
[
2.,
3.]]]),
-
array([[[
4.,
5.],
-
[
6.,
7.]]])]
-
关于stack()函数的一个理解
stack()函数
函数原型为:stack(arrays, axis=0),arrays可以传数组和列表。axis的含义我下面会讲解,我们先来看个例子,然后我会分析输出结果。
import numpy as np
a=[[1,2,3],
[4,5,6]]
print("列表a如下:")
print(a)
print("增加一维,新维度的下标为0")
c=np.stack(a,axis=0)
print(c)
print("增加一维,新维度的下标为1")
c=np.stack(a,axis=1)
print(c)
输出:
列表a如下:
[[1, 2, 3], [4, 5, 6]]
增加一维,新维度下标为0
[[1 2 3]
[4 5 6]]
增加一维,新维度下标为1
[[1 4]
[2 5]
[3 6]]
首先这里arrays我传的是一个列表,现在我开始讲解这个stack()函数的意思,它就是对arrays里面的每个元素(可能是个列表,元组,或者是个numpy的数组)变成numpy的数组后,再对每个元素增加一维(至于维度加在哪里,是靠axis控制的),然后再把这些元素串起来(至于怎么串,我下面会说)。
arrays里面的每个元素必须形状是一样的,例如本例中列表a中的两个元素[1,2,3]和[4,5,6]的形状是一样的,如果把[4,5,6]换成[4,5] ,那么程序会报错!而axis代表的是在哪个维度上加一维,例如axis=0(它是默认的)代表的就是增加的这一维的下标为0,axis等于多少不是随便乱写的,如果参数arrays里面的每个元素是个1维的,那么调用stack()函数增加一维后会变成2维的,所以axis只能等于0和1(维度的下标是从0开始的),而参数axis=0和axis=1得到的结果是不一样的。
例如上面的代码中a列表中的第一个元素为[1,2,3],那么当axis=0的时候,就是在它的中括号外面再加一个中括号,变成[ [1,2,3] ](其实1,2,3之间是没有逗号的,因为stack()函数会先把参数arrays中的每个元素变成numpy的数组,数组之间是没有逗号的,看看上面的代码输出就知道了,这里大家明白就行,我为了方便讲解,下面还会加上逗号),这样最外面那层中括号才代表维度下标为0的那维;当axis=1的时候,就是在里面加个中括号,变成了[ [1],[2],[3] ],这样里面加的那层中括号才代表维度下标为1的那维。同理当axis=0的时候[4,5,6]变成[ [ 4,5,6] ],当axis=1的时候,变成[ [4],[5],[6] ]。下面我们讲如何把增加一维度后的每个元素串起来。
怎么把上面那两个元素增加维度后的结果串起来呢,其实很简单。现在我们已经知道了增加维度无非是增加中括号的意思,至于在哪里加中括号,取决于axis等于几。我们把增加的中括号想像成一个个的箱子。还拿上面的代码来说,当axis=0的时候,我们把套在[1,2,3]外面的中括号(就是[ [1,2,3] ]最外层的那个中括号)看做是箱子A,这个箱子A也会套在[4,5,6]的外面,所以我们就先把[1,2,3]和[4,5,6]放在一起,变成[1,2,3],[4,5,6],然后再一起套上箱子A,变成[ [1,2,3],[4,5,6] ]这就是当axis=0的时候程序的输出结果。
现在再来看当axis=1的时候,对于[1,2,3],我们把套在1外面的箱子(就是上面讲的[ [1],[2],[3] ]中1外面的那层中括号)看做A,套在2外面的看做B,套在3外面的看做C,同理,箱子A也会套在4的外面,箱子B也会套在5的外面,箱子C也会套在6的外面。那么我们就把1和4放一起,2和5放一起,3和6放一起,变成[ 1,4 ,2,5 ,3,6 ]然后把箱子A,B,C分别套在1,4 , 2,5 , 3,6的外面,变成[ [1,4] , [2,5] , [3,6] ]这就是程序中axis=1的时候程序的输出结果。
大家发现了没有,串起来的时候其实就是把arrays中每个元素在相同的位置套箱子的一些小块(这里叫小块这个名词可能不洽当,但是大家明白就行)放在一起后,再套箱子,就是外面套个中括号,这就是堆叠。
参考文献:
1、https://blog.youkuaiyun.com/garfielder007/article/details/51378296 2018.7.8
2、https://blog.youkuaiyun.com/csdn15698845876/article/details/73380803/ 2018.7.8 (关于axis的一个不错的理解)