当参数是列表或元组时,np.c_
的输出有所不同。考虑以下三个行的输出带有列表和元组参数的np.c_的行为
np.c_[[1,2]]
np.c_[(1,2)]
np.c_[(1,2),]
随着list参数,np.c_
返回一个列阵列,如所预期。当参数是一个元组(第二行)时,它返回一个2D行。在元组(第三行)之后,为第一个调用返回一个列数组后的逗号。
有人可以解释这种行为的基本原理吗?
当参数是列表或元组时,np.c_
的输出有所不同。考虑以下三个行的输出带有列表和元组参数的np.c_的行为
np.c_[[1,2]]
np.c_[(1,2)]
np.c_[(1,2),]
随着list参数,np.c_
返回一个列阵列,如所预期。当参数是一个元组(第二行)时,它返回一个2D行。在元组(第三行)之后,为第一个调用返回一个列数组后的逗号。
有人可以解释这种行为的基本原理吗?
有2共同使用情况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_
可以传递1D数组或喜欢2D数组。 但是,这引发了一个问题,np.c_
应该如何识别输入是单个2D数组(如[[1,2],[3,4]]还是1D数组类喜欢的序列(例如[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)
作为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
时的不同处理方式。
上处理参数的第一电平来自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
....
看看代码。文件中的这个和其他类/函数('indexing_tricks'?)是一个方便但有趣的编码。 – hpaulj