np.c_
的输出在其参数是列表或元组时有所不同。考虑以下三行的输出
np.c_[[1,2]]
np.c_[(1,2)]
np.c_[(1,2),]
使用list参数,np.c_
按预期返回列数组。当参数是元组(第二行)时,它返回一个2D行。在元组(第三行)之后添加逗号将返回与第一次调用相同的列数组。
有人可以解释这种行为背后的理由吗?
答案 0 :(得分:5)
np.c_
有两个常见用例:
np.c_
可以接受一系列1D数组:
In [98]: np.c_[[1,2],[3,4]]
Out[98]:
array([[1, 3],
[2, 4]])
或,np.c_
可以接受一系列2D数组:
In [96]: np.c_[[[1,2],[3,4]], [[5,6],[7,8]]]
Out[96]:
array([[1, 2, 5, 6],
[3, 4, 7, 8]])
所以np.c_
可以传递一维数组或2D数组。
但这提出了一个问题:如果输入是单个2D数组(例如[[1,2],[3,4]])或一维数组序列,np.c_
应该如何识别({1}}例如[1,2],[3,4])?
开发人员做出了一个设计决策:如果np.c_
传递了一个元组,那么该参数将被视为一系列独立的数组。如果它传递了非元组(例如列表),那么该对象将被视为单个数组。
因此,np.c_[[1,2], [3,4]]
(相当于np.c_[([1,2], [3,4])]
)会将([1,2], [3,4])
视为两个独立的1D数组。
In [99]: np.c_[[1,2], [3,4]]
Out[99]:
array([[1, 3],
[2, 4]])
相比之下,np.c_[[[1,2], [3,4]]]
会将[[1,2], [3,4]]
视为单个2D数组。
In [100]: np.c_[[[1,2], [3,4]]]
Out[100]:
array([[1, 2],
[3, 4]])
因此,对于您发布的示例:
np.c_[[1,2]]
将[1,2]
视为单个1D数组,因此它将[1,2]转换为2D数组的列:
In [101]: np.c_[[1,2]]
Out[101]:
array([[1],
[2]])
np.c_[(1,2)]
将(1,2)
视为两个独立的数组,因此它将每个值放入其自己的列中:
In [102]: np.c_[(1,2)]
Out[102]: array([[1, 2]])
np.c_[(1,2),]
将元组(1,2),
(相当于((1,2),)
)视为一个类似数组的序列,以便将类似数组视为列:
In [103]: np.c_[(1,2),]
Out[103]:
array([[1],
[2]])
PS。也许比大多数软件包更多,NumPy的历史记录为treating lists and tuples differently。该链接讨论了传递给np.array
时列表和元组如何被区别对待。
答案 1 :(得分:2)
处理参数的第一个级别来自Python解释器,它将[...]转换为对__getitem__
的调用:
In [442]: class Foo():
...: def __getitem__(self,args):
...: print(args)
...:
In [443]: Foo()['str']
str
In [444]: Foo()[[1,2]]
[1, 2]
In [445]: Foo()[[1,2],]
([1, 2],)
In [446]: Foo()[(1,2)]
(1, 2)
In [447]: Foo()[(1,2),]
((1, 2),)
np.c_
是np.lib.index_tricks.AxisConcatenator
的一个实例。这是__getitem__
# handle matrix builder syntax
if isinstance(key, str):
....
mymat = matrixlib.bmat(...)
return mymat
if not isinstance(key, tuple):
key = (key,)
....
for k, item in enumerate(key):
....
除了np.bmat
兼容字符串之外,它将所有输入转换为元组,然后迭代元素。
包含[1,2]
的任何变体都与([1,2],)
相同,即单个元素元组。 (1,2)
是两个将被连接起来的元素。 ([1,2],[3,4])
也是如此。
请注意,numpy
索引还可以区分列表和元组(尽管存在一些不一致)。
In [455]: x=np.arange(24).reshape(2,3,4)
In [456]: x[0,1] # tuple - index for each dim
Out[456]: array([4, 5, 6, 7])
In [457]: x[(0,1)] # same tuple
Out[457]: array([4, 5, 6, 7])
In [458]: x[[0,1]] # list - index for one dim
Out[458]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
In [459]: x[([0,1],)] # same
....