#python #arrays #numpy #concatenation #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)
В результате получается:
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.]]
Комментарии:
1. Большое спасибо. Но кажется очень трудным выяснить, что np.concatenate также может создать элемент списка, чтобы сделать что-то подобное без каких-либо слепых испытаний…официальный документ не дает мне подсказки в этом направлении tbh.
Ответ №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]) lt;__array_function__ internalsgt;: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)
Это не одно и то же. Чтобы получить то же самое, вам нужно сначала применить конкатенацию к g
себе:
In [251]: np.concatenate([e,np.concatenate(g)]) Out[251]: array([1., 2., 3.])
Тем не менее, мы обычно не рекомендуем использовать e=np.concatenate((e,...))
его в цикле. Добавление списка происходит быстрее.