Tôi có một danh sách dài các tọa độ xy và muốn chuyển đổi nó thành mảng có nhiều mảng.tại sao chuyển đổi danh sách 2D dài thành mảng có nhiều mảng chậm?
>>> import numpy as np
>>> xy = np.random.rand(1000000, 2).tolist()
Cách rõ ràng sẽ là:
>>> a = np.array(xy) # Very slow...
Tuy nhiên, các mã trên là bất hợp lý chậm. Thật thú vị, để chuyển đổi danh sách dài đầu tiên, chuyển đổi nó thành mảng numpy, và sau đó chuyển đổi trở lại sẽ nhanh hơn nhiều (20x trên máy tính xách tay của tôi).
>>> def longlist2array(longlist):
... wide = [[row[c] for row in longlist] for c in range(len(longlist[0]))]
... return np.array(wide).T
>>> a = longlist2array(xy) # 20x faster!
Đây có phải là lỗi không đầy đặn?
EDIT:
Đây là một danh sách các điểm (với tọa độ xy) tạo on-the-fly, nên thay vì preallocating một mảng và mở rộng nó khi cần thiết, hoặc duy trì hai danh sách 1D cho x và y, Tôi nghĩ đại diện hiện tại là tự nhiên nhất.
Tại sao vòng lặp thông qua chỉ mục thứ 2 nhanh hơn chỉ mục thứ nhất, do chúng tôi đang lặp qua danh sách python theo cả hai hướng?
EDIT 2:
Dựa trên câu trả lời @ Tiago và , tôi thấy đoạn mã sau hai lần nhanh như phiên bản ban đầu của tôi:
>>> from itertools import chain
>>> def longlist2array(longlist):
... flat = np.fromiter(chain.from_iterable(longlist), np.array(longlist[0][0]).dtype, -1) # Without intermediate list:)
... return flat.reshape((len(longlist), -1))
Nó không phải là một lỗi, đó là một tính năng! – Bitwise
Vậy tính năng này tốt cho điều gì? Điều duy nhất tôi có thể nghĩ về nó để kiểm tra xem mỗi danh sách bên trong có cùng chiều dài hay không, nhưng tôi không nghĩ sẽ mất nhiều thời gian ... – herrlich10
@ herrlich10 danh sách không nhất thiết phải tiếp giáp trong bộ nhớ để 'np. mảng' đang lặp qua chỉ mục đầu tiên (chỉ mục danh sách) và thêm nó vào mảng. Đây là lý do tại sao phải mất nhiều thời gian hơn khi chỉ mục đầu tiên lớn hơn nhiều so với chỉ số thứ hai. – tiago