为啥将 np.concatenate 与 for 循环和列表理解一起使用的结果不一样?
Posted
技术标签:
【中文标题】为啥将 np.concatenate 与 for 循环和列表理解一起使用的结果不一样?【英文标题】:Why the result of using np.concatenate with for loop and list comprehension is not the same?为什么将 np.concatenate 与 for 循环和列表理解一起使用的结果不一样? 【发布时间】:2022-01-15 00:21:17 【问题描述】:我想知道为什么这两段代码的结果不同,想知道如何只使用for循环来达到与列表推导相同的结果:
a = []
c = []
n = np.array([1,2],dtype=np.float32)
m = np.array([1,3],dtype=np.float32)
b = np.array([3], dtype=np.float32)
a.append([n, m, b])
a.append([n, m, b])
a.append([n, m, b])
e = np.array([])
for obs,_,act in a:
g = [obs,act]
e = np.concatenate([e,g])
e = np.array([e])
f = np.array( [np.concatenate([obs,act]) for obs,_,act in a ])
print("using for loop:\n", e)
print("using list comprehension:\n", f)
结果是:
using for loop:
[[array([1., 2.], dtype=float32) array([3.], dtype=float32)
array([1., 2.], dtype=float32) array([3.], dtype=float32)
array([1., 2.], dtype=float32) array([3.], dtype=float32)]]
using list comprehension:
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
为什么?以及如何使 for 循环具有与列表理解相同的结果?
【问题讨论】:
【参考方案1】:这是因为您没有使用相同操作。试试这样的:
a = []
c = []
n = np.array([1,2],dtype=np.float32)
m = np.array([1,3],dtype=np.float32)
b = np.array([3], dtype=np.float32)
a.append([n, m, b])
a.append([n, m, b])
a.append([n, m, b])
e = []
for obs,_,act in a:
g = [obs,act]
e.append(np.concatenate(g))
e = np.array(e)
f = np.array([np.concatenate([obs,act]) for obs,_,act in a ])
print("using for loop:\n", e)
print("using list comprehension:\n", f)
using for loop:
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
using list comprehension:
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
【讨论】:
非常感谢。但似乎很难发现 np.concatenate 也可以制作一个列表元素来做这样的事情而无需任何盲目试验......官方文档没有给我这个方向的提示。【参考方案2】:你的a
In [238]: a
Out[238]:
[[array([1., 2.], dtype=float32),
array([1., 3.], dtype=float32),
array([3.], dtype=float32)],
[array([1., 2.], dtype=float32),
array([1., 3.], dtype=float32),
array([3.], dtype=float32)],
[array([1., 2.], dtype=float32),
array([1., 3.], dtype=float32),
array([3.], dtype=float32)]]
一个g
:
In [239]: obs,_,act = a[0]
In [240]: g = [obs,act]
In [241]: g
Out[241]: [array([1., 2.], dtype=float32), array([3.], dtype=float32)]
理解使用:
In [243]: np.concatenate(g)
Out[243]: array([1., 2., 3.], dtype=float32)
迭代(在第一个循环中):
In [247]: e = np.array([])
In [248]: np.concatenate([e,g])
<__array_function__ internals>:5: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
Out[248]:
array([array([1., 2.], dtype=float32), array([3.], dtype=float32)],
dtype=object)
这不是加入同样的事情。要获得相同的效果,您需要先将 concatenate 应用于 g
本身:
In [251]: np.concatenate([e,np.concatenate(g)])
Out[251]: array([1., 2., 3.])
也就是说,我们通常不鼓励在循环中使用 e=np.concatenate((e,...))
。列表追加速度更快。
【讨论】:
以上是关于为啥将 np.concatenate 与 for 循环和列表理解一起使用的结果不一样?的主要内容,如果未能解决你的问题,请参考以下文章