2016-12-09 12 views
5

Tôi đã thực hiện quá nhiều thời gian yêu cầu tôi sử dụng chức năng .append() của list và cũng có chức năng numpy.append() cho các mảng có nhiều mảng. Tôi nhận thấy rằng cả hai phát triển rất chậm khi kích thước của mảng lớn.Là mảng numpy và danh sách python tối ưu hóa để được tự động phát triển?

Tôi cần một mảng đang phát triển động cho kích thước khoảng 1 triệu phần tử. Tôi có thể thực hiện điều này bản thân mình, giống như std::vector được thực hiện bằng C++, bằng cách thêm chiều dài bộ đệm (độ dài dự trữ) mà không thể truy cập từ bên ngoài. Nhưng tôi có phải tái tạo lại bánh xe không? Tôi tưởng tượng nó nên được thực hiện ở đâu đó. Vì vậy, câu hỏi của tôi là: Liệu một điều như vậy tồn tại trong Python?

Ý của tôi là: Có trong Python một loại mảng có khả năng phát triển động với độ phức tạp thời gian là O(C) hầu hết thời gian không?

+0

bạn có nghĩa là mảng (https://docs.python.org/2/library/array.html) không? hoặc danh sách? bởi vì đó là hai thứ khác nhau trong python. Mảng làm chậm phát triển trong python. – MooingRawr

+1

(Chỉ cần một số suy nghĩ): Tôi nghĩ rằng danh sách của CPython/arraylist-hành vi tương tự như std :: vector, nhưng không cung cấp cho bạn hướng dẫn kiểm soát có sẵn trong c + +. Tôi có thể tưởng tượng, rằng có thể có nhiều khả năng hơn về phía thuật toán trong các trường hợp sử dụng của bạn (đặc biệt là np.append không phải là một hoạt động rất phổ biến). Nếu không, bạn luôn có thể xây dựng một số std :: vector wrapper với [cython] (http://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html). Tôi cũng thích đề cập đến deque của blue_note khi tôi yêu quá trình 2 bước phát triển dữ liệu dựa trên danh sách được liên kết + biến đổi mảng ở cuối. – sascha

+0

@MooingRawr Lý do tại sao tôi tham gia vào danh sách này là bởi vì nó không phải là liên tiếp trong bộ nhớ, và vẫn còn chậm với mảng lớn hơn. Vì vậy, tôi thành thật không hiểu những gì đang xảy ra. –

Trả lời

1

Cả hai đều sử dụng một mảng cơ bản. Thay vào đó, bạn có thể sử dụng collections.deque được tạo để bổ sung và loại bỏ các phần tử ở cả hai đầu bằng O (1) phức tạp

0

Bộ nhớ của mảng được mô tả trong tài liệu và được thảo luận ở đây rất nhiều. Danh sách bố trí bộ nhớ cũng đã được thảo luận, mặc dù thường chỉ tương phản với numpy.

Mảng sần có bộ đệm dữ liệu kích thước cố định. 'phát triển' nó đòi hỏi phải tạo một mảng mới và sao chép dữ liệu vào nó. np.concatenate thực hiện điều đó trong mã được biên dịch. np.append cũng như tất cả các chức năng stack sử dụng concatenate.

Danh sách có, như tôi hiểu nó, một bộ đệm dữ liệu liền kề có chứa con trỏ đến các đối tượng khác trong đó trong memeory. Python duy trì một số khả năng tự do trong bộ đệm đó, vì vậy việc bổ sung với list.append tương đối nhanh và dễ dàng. Nhưng khi các freespace lấp đầy, nó đã tạo ra một bộ đệm mới và sao chép con trỏ. Tôi có thể thấy nơi mà có thể tốn kém với các danh sách lớn.

Vì vậy, danh sách sẽ lưu trữ con trỏ cho mỗi phần tử, cộng với chính phần tử đó (ví dụ: dấu phẩy) ở một nơi khác trong bộ nhớ. Ngược lại, mảng nổi lưu trữ các bản thân float như các byte tiếp giáp trong bộ đệm của nó. (Đối tượng mảng dtype giống như danh sách).

Cách được khuyến nghị để tạo mảng lặp lại là tạo danh sách với append và tạo mảng một lần ở cuối. Lặp đi lặp lại np.append hoặc np.concatenate là tương đối đắt tiền.

deque đã được đề cập. Tôi không biết nhiều về cách lưu trữ dữ liệu của nó. Các tài liệu nói rằng nó có thể thêm các yếu tố vào đầu dễ dàng như ở phần cuối, nhưng truy cập ngẫu nhiên chậm hơn so với một danh sách. Điều đó ngụ ý rằng nó lưu trữ dữ liệu trong một số loại danh sách liên kết, để tìm kiếm các yếu tố nth yêu cầu đi qua các liên kết n-1 trước khi nó. Vì vậy, có một sự cân bằng giữa tăng trưởng dễ dàng và tốc độ truy cập.

Thêm phần tử vào đầu danh sách yêu cầu tạo danh sách con trỏ mới, với (các) con trỏ mới khi bắt đầu. Vì vậy, thêm, và loại bỏ các yếu tố từ đầu của một danh sách thường xuyên, là đắt hơn nhiều so với làm điều đó ở cuối.

Phần mềm đề xuất nằm ngoài mục đích SO cốt lõi. Những người khác có thể đưa ra đề xuất, nhưng đừng ngạc nhiên nếu điều này bị đóng.

Có các định dạng tệp như HDF5 được thiết kế cho các tập dữ liệu lớn.Chúng phù hợp với sự tăng trưởng với các tính năng như 'chunking'. Và có tất cả các loại gói cơ sở dữ liệu.

+0

Tôi xin lỗi, nhưng đây không phải là đề xuất phần mềm, và nếu đề xuất một cách để làm mọi thứ là đề xuất phần mềm, thì 99% các bài viết của SO phải được đóng lại. Trong khi tôi cảm ơn bạn đã cung cấp thông tin, câu đó rất không gây cản trở và gây khó chịu và là một người rơm. Xin vui lòng loại bỏ nó. –

+0

Tôi sử dụng HDF5 cho cùng một dự án, btw, nhưng tôi đang nói về những thứ trong bộ nhớ, không phải trong tệp. –

+0

Cách bạn sử dụng dữ liệu cũng quan trọng như cách bạn phát triển dữ liệu. Thông thường bạn sử dụng nó nhiều lần, nhưng chỉ phát triển nó một lần. Tôi muốn nghiêng về việc sử dụng danh sách nối thêm để tạo mảng từ các phần nhỏ (số/hàng tại một thời điểm), và mảng nối để nối các mảng lớn thành các mảng lớn hơn - cho đến khi tôi bắt đầu đạt tới giới hạn bộ nhớ. – hpaulj

Các vấn đề liên quan