[英]How does numpy.concatenate work on lists
我试图弄清楚为什么以下代码不起作用:
import numpy as np
failList = [[[1], [2]],
[[3, 4, 5, 6], [7]],
[[8], [9]],
[[10], [11, 12]],
[[13], [14, 15, 16]]]
goodList = [[[1], [2], [3, 4, 5, 6], [7], [8]],
[[9], [10], [11, 12], [13], [14, 15, 16]]]
goodList2 = [[[1], [2], [3, 4, 5, 6], [7], [8]],
[[9], [10], [11, 12], [13], [14, 15, 16]],
[[9], [10], [11, 12], [13], [14, 15, 16]]]
myLists = [failList, goodList, goodList]
for l in myLists:
print([len(l[i]) for i in range(len(l))])
print([len(l[i][j]) for i in range(len(l)) for j in range(len(l[i]))])
try:
np.concatenate(l)
print("worked")
except:
print("failed")
输出为:
[2, 2, 2, 2, 2]
[1, 1, 4, 1, 1, 1, 1, 2, 1, 3]
failed
[5, 5]
[1, 1, 4, 1, 1, 1, 1, 2, 1, 3]
worked
[5, 5, 5]
[1, 1, 4, 1, 1, 1, 1, 2, 1, 3, 1, 1, 2, 1, 3]
worked
有人可以解释一下,为什么第一个列表不能被串联,而其他人可以吗?
concatenate
根据每个列表元素创建一个数组,然后将其连接到所需的轴上。 如果形状不匹配,则会引发错误:
In [80]: failList = [[[1], [2]],
...: [[3, 4, 5, 6], [7]],
...: [[8], [9]],
...: [[10], [11, 12]],
...: [[13], [14, 15, 16]]]
...:
In [81]: [np.array(a) for a in failList]
Out[81]:
[array([[1],
[2]]),
array([list([3, 4, 5, 6]), list([7])], dtype=object),
array([[8],
[9]]),
array([list([10]), list([11, 12])], dtype=object),
array([list([13]), list([14, 15, 16])], dtype=object)]
In [82]: [np.array(a).shape for a in failList]
Out[82]: [(2, 1), (2,), (2, 1), (2,), (2,)]
In [83]: np.concatenate([np.array(a) for a in failList])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-83-c3434632bd7e> in <module>()
----> 1 np.concatenate([np.array(a) for a in failList])
ValueError: all the input arrays must have same number of dimensions
对于不同种类的数组, failedList
的元素,有些是2d数字,有些是1d对象。 concatenate
不能加入那些。
column_stack
确实起作用:
In [87]: np.column_stack(failList)
Out[87]:
array([[1, list([3, 4, 5, 6]), 8, list([10]), list([13])],
[2, list([7]), 9, list([11, 12]), list([14, 15, 16])]],
dtype=object)
In [88]: _.shape
Out[88]: (2, 5)
这是因为它将(2,)形状的数组重塑为(2,1)。 现在,它具有一个5(2,1)数组的列表,可以在第二维上进行连接,从而生成一个(2,5)数组。 但是请注意,它是对象dtype。 有些元素是整数,有些是列表(大小不同)。
串联元组(或列表)中的列表应具有相同的维 。
您可以在实现np.concatenate
的github源代码中看到399行。
if (PyArray_NDIM(arrays[iarrays]) != ndim) {
PyErr_SetString(PyExc_ValueError,
"all the input arrays must have same "
"number of dimensions");
return NULL;
}
PyArray_NDIM
do 给出所有尺寸的长度
在您的情况下, failList
中的列表没有相同的维。 您可以通过下面的代码进行检查。
import numpy as np
failList = [[[1], [2]],
[[3, 4, 5, 6], [7]],
[[8], [9]],
[[10], [11, 12]],
[[13], [14, 15, 16]]]
goodList = [[[1], [2], [3, 4, 5, 6], [7], [8]],
[[9], [10], [11, 12], [13], [14, 15, 16]]]
goodList2 = [[[1], [2], [3, 4, 5, 6], [7], [8]],
[[9], [10], [11, 12], [13], [14, 15, 16]],
[[9], [10], [11, 12], [13], [14, 15, 16]]]
faileShapes = [np.shape(i) for i in failList]
print(faileShapes)
goodShapes = [np.shape(i) for i in goodList]
print(goodShapes)
goodShapes2 = [np.shape(i) for i in goodList2]
print(goodShapes2)
# printed console
# [(2, 1), (2,), (2, 1), (2,), (2,)]
# [(5,), (5,)]
# [(5,), (5,), (5,)]
原始答案(错误):
根据文档 :
数组必须具有相同的形状,除了与轴对应的尺寸(默认为第一个)。
您的第一个列表具有以下属性:内部列表的长度不同(分别为6和4)。 在您的良好列表中,所有内部列表的长度都相同5。
编辑 :对不起,我没有注意到其中一个括号,所以我错误地将您的failList
的形状视为错误。
正确的答案是在failList中,子列表具有不同的形状 :
>>> np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]).shape
(3,3) # because all lists have the same lengths, so NumPy treats as multi-dim array
>>> np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]]).shape
(3,) # because all lists have different lengths, so NumPy treats as an array of lists
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.