Python nối thêm danh sách nhanh như thế nào?

Gần đây tôi đang làm việc trong một dự án xử lý ảnh kỹ thuật số. Điều chỉnh siêu tham số mất khá nhiều thời gian trước khi tôi có được độ chính xác mong muốn. Tất cả chỉ vì ký sinh trùng quá mức và phần cứng cấp thấp vô dụng của tôi

Đối với mỗi lần thực hiện, máy của tôi mất khoảng 15–20 phút. 20 phút để xử lý 20 000 mục nhập. Tôi tưởng tượng nếu tôi đang làm việc trên bộ dữ liệu 1 triệu bản ghi, tôi sẽ phải đợi trái đất quay hoàn toàn trước khi kết thúc khóa đào tạo

Tôi hài lòng với độ chính xác của mô hình. Tuy nhiên, tôi muốn thử nhiều kiến ​​trúc Mạng thần kinh chuyển đổi (CNN) khác trước khi gửi mã của mình. Do đó, tôi quyết định tìm kiếm các phòng tối ưu hóa trong mã của mình

Bởi vì tôi đang sử dụng các thuật toán máy học dựng sẵn nằm trong PyPi — Scikit-Learn và Tensorflow — rất ít chương trình con còn lại để tối ưu hóa. Một tùy chọn là tăng mã của tôi về cấu trúc dữ liệu. Tôi đang lưu trữ dữ liệu trong danh sách và vì NumPy siêu nhanh nên tôi nghĩ sử dụng nó có thể là một lựa chọn khả thi

Đoán xem điều gì đã xảy ra sau khi chuyển đổi mã danh sách của tôi thành mã mảng NumPy?

Tôi rất ngạc nhiên, thời gian thực hiện không giảm. Thay vào đó nó tăng vọt

Điều đó đang được nói, trong bài đăng này, tôi sẽ hướng dẫn bạn tình huống chính xác mà các danh sách kết thúc hoạt động tốt hơn các mảng NumPy

NumPy và Danh sách

Hãy để chúng tôi thảo luận về sự khác biệt giữa mảng và danh sách NumPy, để bắt đầu với

NumPy là thư viện Python thực tế cho thao tác mảng N chiều và tính toán tính toán. Nó là mã nguồn mở, dễ sử dụng, thân thiện với bộ nhớ và nhanh như chớp

Ban đầu được gọi là 'Numeric', NumPy đặt khuôn khổ cho nhiều thư viện khoa học dữ liệu như SciPy, Scikit-Learn, Panda, v.v.

Trong khi danh sách Python lưu trữ một tập hợp các đối tượng dữ liệu có thể thay đổi, có thứ tự, thì mảng NumPy chỉ lưu trữ một loại đối tượng duy nhất. Vì vậy, chúng ta có thể nói rằng các mảng NumPy sống dưới ô của danh sách. Do đó, không có gì mảng NumPy làm danh sách không

Tuy nhiên, khi nói đến NumPy nói chung. Numpy không chỉ bao gồm thao tác mảng mà còn nhiều thói quen khác như phép toán nhị phân, đại số tuyến tính, hàm toán học, v.v. Tôi tin rằng nó bao gồm nhiều hơn một người có thể cần

Điều tiếp theo cần xem xét là tại sao chúng ta thường sử dụng mảng NumPy trên danh sách

Câu trả lời ngắn gọn, mà tôi tin rằng mọi người đọc bài viết này đều biết, là. nó nhanh hơn

NumPy thực sự rất nhanh, mặc dù Python được biết đến là chậm. Điều này là do NumPy đóng vai trò là trình bao bọc xung quanh C và Fortran. Và khỏi phải nói hai em này nhanh như thế nào

Mảng NumPy nhanh hơn danh sách

Trước khi chúng tôi thảo luận về trường hợp mảng NumPy trở nên chậm như ốc sên, cần xác minh giả định rằng mảng NumPy thường nhanh hơn danh sách

Để làm điều đó, chúng tôi sẽ tính giá trị trung bình của mảng 1 triệu phần tử bằng cả NumPy và danh sách. Mảng được tạo ngẫu nhiên

Đoạn mã sau là một ví dụ

"""General comparison between NumPy and lists"""import numpy as np
from time import time
#Random numpy array
numpy_array = np.random.rand(1000000)
list_conv = list(numpy_array)
#Start timing NumPy compuation
start1 = time()
#Compute the mean using NumPy
numpy_mean = np.mean(numpy_array)
print(f"Computing the mean using NumPy: {numpy_mean}")
#End timing
end1 = time()
#Time taken
time1 = end1 - start1
print(f"Computation time: {time1}")
#Start timing list computation
start2 = time()
#Compute the mean using lists
list_mean = np.mean(list_conv)
print(f"Computing the mean using lists: {list_mean}")
#End timing
end2 = time()
#Time taken
time2 = end2 - start2
print(f"Computation time: {time2}")
#Check results are equal
assert abs(numpy_mean - list_mean) <= 10e-6, "Alert, means are not equal"

Đầu ra máy của tôi như sau

Computing the mean using NumPy: 0.4996098756973947
Computation time: 0.01397562026977539
Computing the mean using lists: 0.4996098756973947
Computation time: 0.17974257469177246

Theo dự đoán, chúng ta có thể thấy rằng mảng NumPy nhanh hơn đáng kể so với danh sách. Sự khác biệt đáng kể về tốc độ là đáng chú ý

Điều đó nói rằng, chúng ta có thể khái quát hóa và nói rằng mảng NumPy luôn nhanh hơn danh sách không?

Hóa ra mảng NumPy không phải lúc nào cũng vượt qua danh sách. Các danh sách cũng có những mánh khóe, điều này sẽ đưa chúng ta đến phần tiếp theo

Mảng NumPy KHÔNG phải lúc nào cũng nhanh hơn danh sách

Nếu các danh sách là vô dụng so với các mảng NumPy, thì có lẽ chúng đã bị cộng đồng Python bán phá giá

Một ví dụ trong đó danh sách nổi lên và tỏa sáng so với mảng NumPy là hàm append(). "append()" thêm các giá trị vào cuối cả hai danh sách và mảng NumPy. Đây là một chức năng phổ biến và rất thường được sử dụng

Kịch bản bên dưới thể hiện sự so sánh giữa danh sách'append() và NumPy's append(). Mã chỉ cần thêm các số từ 0 đến 99 999 vào cuối danh sách và mảng NumPy

"""numpy.append() vs list.append()"""
import numpy as np
from time import time
def numpy_append():
arr = np.empty((1, 0), int)
for i in range(100000):
arr = np.append(arr, np.array(i))
return arr
def list_append():
list_1 = []
for i in range(100000):
list_1.append(i)
return list_1
def main ():
#Start timing numpy array
start1 = time()
new_np_arr = numpy_append()
#End timing
end1 = time()
#Time taken
print(f"Computation time of the numpy array : {end1 - start1}")
#Start timing numpy array
start2 = time()
new_list = list_append()
#End timing
end2 = time()
#Time taken
print(f"Computation time of the list: {end2 - start2}")
#Testing
assert list(new_np_arr) == new_list, "Arrays tested are not the same"
if __name__ == "__main__":
main()

Máy của tôi tạo ra đầu ra sau

Computation time of the numpy array : 2.779465675354004
Computation time of the list: 0.010703325271606445

Như chúng ta có thể thấy, trong ví dụ này, danh sách hoạt động tốt hơn mảng NumPy. Numpy đã hoạt động kém đến mức nó đã bị vượt qua hơn 2000%

Trường hợp chứng minh rằng NumPy không nên được coi là tùy chọn “luôn luôn truy cập” bất cứ khi nào có liên quan đến tốc độ. Thay vào đó, cần xem xét cẩn thận

Có gì sai với Numpy. nối thêm?

Để làm sáng tỏ bí ẩn này, chúng ta sẽ truy cập mã nguồn của NumPy. Hàm append() cho biết như sau

"Append values to the end of an array.    Parameters
----------
arr : array_like
Values are appended to a copy of this array.
values : array_like
These values are appended to a copy of `arr`. It must be of
the correct shape (the same shape as `arr`, excluding
`axis`). If `axis` is not specified, `values` can be any
shape and will be flattened before use.
axis : int, optional
The axis along which `values` are appended. If `axis` is
not given, both `arr` and `values` are flattened before use.
Returns
-------
append : ndarray
A copy of `arr` with `values` appended to `axis`. Note that
`append` does not occur in-place: a new array is allocated
and filled. If `axis` is None, `out` is a flattened array."

Sau khi đọc kỹ chuỗi tài liệu, chúng ta có thể thấy một “ghi chú” về những gì hàm trả về. Nó nói rằng quá trình nối thêm không xảy ra trong cùng một mảng. Thay vào đó, một mảng mới được tạo và lấp đầy

Tuy nhiên, trong danh sách, mọi thứ rất khác. Quá trình điền danh sách nằm trong chính danh sách đó và không có danh sách mới nào được tạo

Tóm lại, chúng ta có thể thấy rằng quá trình copy-fill của

Computing the mean using NumPy: 0.4996098756973947
Computation time: 0.01397562026977539
Computing the mean using lists: 0.4996098756973947
Computation time: 0.17974257469177246
0 là thứ khiến nó trở thành một chi phí

mang đi

Không có dầu rắn trong lập trình

Phát hiện của chúng tôi cho thấy thực tế là mảng NumPy không phải là giải pháp cho mọi vấn đề về hiệu suất. Và người ta không nên bịt mắt bắt tay vào hành động trước khi tính đến tất cả các lựa chọn. Làm điều này cũng tối đa hóa cơ hội tạo ra mã được thiết kế tốt hơn

Ngoài ra, khám phá nhiều con đường thông qua thử nghiệm đảm bảo rằng cuối cùng người ta sẽ không hối hận khi chọn lựa chọn này thay vì lựa chọn kia. Và quan trọng hơn, thử nghiệm phát hiện thông tin sai lệch

Tóm lại, và như một phần thưởng cho việc gắn bó với tôi cho đến thời điểm này, đây là một trích dẫn sâu sắc từ A. Einstein tóm tắt quan điểm từ bài đăng này

“Không có thử nghiệm nào có thể chứng minh tôi đúng;

Nếu bạn thấy điều này sâu sắc, hãy cân nhắc trở thành thành viên trả phí với $5/tháng. Nếu bạn sử dụng liên kết này, tôi sẽ nhận được một vết cắt nhỏ

Danh sách python có chậm không?

append đôi khi sẽ phải sao chép tất cả các thành phần của danh sách sang danh sách lớn hơn,. việc nối thêm phải chậm hơn so với việc phân bổ trước toàn bộ độ dài của danh sách và gán cho các chỉ mục riêng lẻ của danh sách đó (tất nhiên bạn chỉ có thể làm điều đó nếu bạn .

Phương pháp nào nhanh hơn trong danh sách nối thêm hoặc chèn?

Nối thêm vào cuối danh sách, trong khi chèn thêm vào trước một chỉ mục đã chỉ định. Chèn chậm hơn khi so sánh với chắp thêm .

Cái gì nhanh hơn append python?

Vì vậy, khi bạn thêm các mục liên tục, bạn nên ưu tiên. append() , nếu không thì bạn nên sử dụng . mở rộng() .

Việc thêm vào một tập hợp có nhanh hơn danh sách python không?

Nói chung, danh sách nhanh hơn tập hợp . Nhưng trong trường hợp tìm kiếm một phần tử trong tập hợp, các tập hợp sẽ nhanh hơn vì các tập hợp đã được triển khai bằng cách sử dụng bảng băm. Vì vậy, về cơ bản Python không phải tìm kiếm toàn bộ, điều đó có nghĩa là độ phức tạp thời gian trung bình là O(1).