简体   繁体   中英

Why the result of using np.concatenate with for loop and list comprehension is not the same?

I am wondering why the results of these two pieces of code are different,and want to know how to use only for loop to achieve the same result as list comprehension:

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)

The result is:

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.]]

why?and how to make the for loop to have the same result as list comprehension?

It is because you are not using the same operation. Try this:

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.]]

Your 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)]]

One 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)]

The comprehension uses:

In [243]: np.concatenate(g)
Out[243]: array([1., 2., 3.], dtype=float32)

The iteration does (in the first loop):

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)

That's not joining the same things. To get the same thing, you need to first apply concatenate to g itself:

In [251]: np.concatenate([e,np.concatenate(g)])
Out[251]: array([1., 2., 3.])

That said, we generally discourage using e=np.concatenate((e,...)) in a loop. List append is faster.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM