khởi tạo một mảng numpy


129

Có cách nào để khởi tạo một mảng numpy của một hình dạng và thêm vào nó không? Tôi sẽ giải thích những gì tôi cần với một ví dụ danh sách. Nếu tôi muốn tạo một danh sách các đối tượng được tạo trong một vòng lặp, tôi có thể làm:

a = []
for i in range(5):
    a.append(i)

Tôi muốn làm một cái gì đó tương tự với một mảng numpy. Tôi biết về vstack, concatenate, v.v. Tuy nhiên, có vẻ như những điều này đòi hỏi hai mảng numpy làm đầu vào. Cái tôi cần là:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

Các big_arraynên có một hình dạng (10,4). làm như thế nào?


BIÊN TẬP:

Tôi muốn thêm làm rõ sau đây. Tôi biết rằng tôi có thể xác định big_array = numpy.zeros((10,4))và sau đó điền vào. Tuy nhiên, điều này đòi hỏi phải chỉ định kích thước của big_array trước. Tôi biết kích thước trong trường hợp này, nhưng nếu tôi không có thì sao? Khi chúng tôi sử dụng .appendchức năng mở rộng danh sách trong python, chúng tôi không cần biết trước kích thước cuối cùng của nó. Tôi tự hỏi nếu một cái gì đó tương tự tồn tại để tạo ra một mảng lớn hơn từ các mảng nhỏ hơn, bắt đầu với một mảng trống.


Ngẫu nhiên mẫu mã đầu tiên của bạn có thể được viết gọn gàng và ngắn gọn như một cách hiểu danh sách : [i for i in range(5)]. (Tương đương : list(range(5)), mặc dù đây là một ví dụ giả định.)
Katriel

Giải pháp nào hiệu quả với bạn? Tôi đang cố gắng làm một cái gì đó tương tự như x = numpy.array()cách chúng ta sẽ làm với một danh sách như y = []; nhưng nó không hoạt động
kRazzy R

Câu trả lời:


160

numpy.zeros

Trả về một mảng mới có hình dạng và kiểu đã cho, chứa đầy các số không.

hoặc là

numpy.ones

Trả về một mảng mới của hình dạng và kiểu đã cho, chứa đầy những cái.

hoặc là

numpy.empty

Trả về một mảng mới có hình dạng và kiểu đã cho, mà không khởi tạo các mục.


Tuy nhiên, tâm lý trong đó chúng tôi xây dựng một mảng bằng cách nối các phần tử vào danh sách không được sử dụng nhiều trong numpy, bởi vì nó kém hiệu quả hơn (kiểu dữ liệu numpy gần với mảng C bên dưới hơn). Thay vào đó, bạn nên phân bổ lại mảng theo kích thước mà bạn cần, và sau đó điền vào các hàng. Bạn có thể sử dụng numpy.appendnếu bạn phải, mặc dù.


2
Tôi biết rằng tôi có thể đặt big_array = numpy.zeros và sau đó điền nó với các mảng nhỏ được tạo. Tuy nhiên, điều này yêu cầu tôi chỉ định kích thước của big_array trước. Có gì giống như .append của chức năng danh sách mà tôi không có chỉ định kích thước trước. Cảm ơn!
Curious2learn

2
@ Curious2learn. Không, không có gì giống như nối vào Numpy. Có các hàm ghép các mảng hoặc xếp chúng bằng cách tạo các mảng mới, nhưng chúng không làm như vậy bằng cách nối thêm. Điều này là do cách các cấu trúc dữ liệu được thiết lập. Mảng Numpy được tạo ra để nhanh chóng nhờ khả năng lưu trữ các giá trị gọn hơn, nhưng chúng cần phải có kích thước cố định để đạt được tốc độ này. Danh sách Python được thiết kế để linh hoạt hơn với chi phí tốc độ và kích thước.
Justin Peel

3
@Cquil: tốt, có một appendnumpy. Chỉ là nó không hiệu quả khi không phân bổ (trong trường hợp này, kém hiệu quả hơn nhiều, vì appending sao chép toàn bộ mảng mỗi lần), vì vậy đó không phải là một kỹ thuật tiêu chuẩn.
Katriel

1
Điều gì nếu chỉ một phần của np.emptymảng được điền bởi các giá trị? Còn các mặt hàng "trống" còn lại thì sao?
Lee

1
Nếu bạn chỉ biết chiều rộng (ví dụ cần thiết cho np.concatenate()), bạn có thể khởi tạo bằng : np.empty((0, some_width)). 0, vì vậy mảng đầu tiên của bạn sẽ không phải là rác.
NumeSanguis

40

Cách tôi thường làm là bằng cách tạo một danh sách thông thường, sau đó nối các công cụ của tôi vào đó và cuối cùng chuyển đổi danh sách thành một mảng khó hiểu như sau:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

tất nhiên đối tượng cuối cùng của bạn chiếm gấp đôi dung lượng trong bộ nhớ ở bước tạo, nhưng việc thêm vào danh sách python rất nhanh và việc tạo bằng np.array () cũng vậy.


11
Đây không phải là hướng đi nếu bạn biết kích thước của mảng trước thời hạn , tuy nhiên ... tôi kết thúc việc sử dụng phương pháp này thường xuyên khi tôi không biết mảng sẽ kết thúc lớn như thế nào. Ví dụ, khi đọc dữ liệu từ một tập tin hoặc một quá trình khác. Nó không thực sự khủng khiếp như ban đầu có vẻ như vì trăn và numpy khá thông minh.
travc

18

Được giới thiệu trong numpy 1.8:

numpy.full

Trả về một mảng mới có hình dạng và kiểu đã cho, chứa đầy fill_value.

Ví dụ:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])

13

Mảng tương tự cho con trăn

a = []
for i in range(5):
    a.append(i)

Là:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)

5
@NicholasTJ: empty((0))khởi tạo một mảng numpy.
Adobe

2
dấu ngoặc trong np.empty ((0)) là dự phòng.
Szymon Roziewski

7

numpy.fromiter() là những gì bạn đang tìm kiếm:

big_array = numpy.fromiter(xrange(5), dtype="int")

Nó cũng hoạt động với các biểu thức của trình tạo, ví dụ:

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

Nếu bạn biết trước độ dài của mảng, bạn có thể chỉ định nó với đối số 'đếm' tùy chọn.


2
Tôi thực sự đã chạy timeit và tôi nghĩ rằng np.fromiter () có thể chậm hơn np.array (). timeit ("np.array (i for i in xrange (100))", setup = "import numpy as np", number = 10000) -> 0.02539992332458496, so với timeit ("np.fromiter ((i cho i trong xrange ( 100)), dtype = int) ", setup =" nhập numpy dưới dạng np ", số = 10000) -> 0.13351011276245117
hlin117

6

Bạn muốn tránh các vòng lặp rõ ràng nhất có thể khi thực hiện tính toán mảng, vì điều đó làm giảm tốc độ đạt được từ hình thức tính toán đó. Có nhiều cách để khởi tạo một mảng numpy. Nếu bạn muốn nó chứa đầy số không, hãy làm như katrielalex đã nói:

big_array = numpy.zeros((10,4))

EDIT: Bạn đang thực hiện loại trình tự nào? Bạn nên kiểm tra các hàm numpy khác nhau tạo ra các mảng, như numpy.linspace(start, stop, size)(số cách đều nhau) hoặc numpy.arange(start, stop, inc). Khi có thể, các hàm này sẽ tạo ra các mảng nhanh hơn đáng kể so với thực hiện cùng một công việc trong các vòng lặp rõ ràng


5

Đối với ví dụ mảng đầu tiên của bạn sử dụng,

a = numpy.arange(5)

Để khởi tạo big_array, hãy sử dụng

big_array = numpy.zeros((10,4))

Điều này giả định rằng bạn muốn khởi tạo với số không, điều này khá điển hình, nhưng có nhiều cách khác để khởi tạo một mảng trong numpy .

Chỉnh sửa: Nếu bạn không biết trước kích thước của big_array, trước tiên, tốt nhất là xây dựng danh sách Python bằng cách nối thêm và khi bạn có mọi thứ được thu thập trong danh sách, hãy chuyển đổi danh sách này thành một mảng gọn gàng bằng cách sử dụng numpy.array(mylist). Lý do cho điều này là các danh sách có nghĩa là tăng trưởng rất hiệu quả và nhanh chóng, trong khi numpy.concatenate sẽ rất kém hiệu quả do các mảng numpy không dễ dàng thay đổi kích thước. Nhưng một khi mọi thứ được thu thập trong một danh sách và bạn biết kích thước mảng cuối cùng, một mảng gọn gàng có thể được xây dựng một cách hiệu quả.


5

Để khởi tạo một mảng numpy với một ma trận cụ thể:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

đầu ra:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]

3

Bất cứ khi nào bạn ở trong tình huống sau:

a = []
for i in range(5):
    a.append(i)

và bạn muốn một cái gì đó tương tự trong numpy, một số câu trả lời trước đây đã chỉ ra các cách để làm điều đó, nhưng như @katrielalex chỉ ra các phương pháp này không hiệu quả. Cách hiệu quả để làm điều này là xây dựng một danh sách dài và sau đó định hình lại nó theo cách bạn muốn sau khi bạn có một danh sách dài. Ví dụ: giả sử tôi đang đọc một số dòng từ một tệp và mỗi hàng có một danh sách các số và tôi muốn xây dựng một mảng hình dạng gọn gàng (số dòng đọc, độ dài của vectơ trong mỗi hàng). Đây là cách tôi sẽ làm nó hiệu quả hơn:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array

2

Tôi nhận ra rằng điều này hơi muộn, nhưng tôi không nhận thấy bất kỳ câu trả lời nào khác đề cập đến việc lập chỉ mục vào mảng trống:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

Bằng cách này, bạn sắp xếp lại toàn bộ mảng kết quả numpy.emptyvà điền vào các hàng khi bạn sử dụng phép gán được lập chỉ mục.

Hoàn toàn an toàn để phân bổ emptythay vì zerostrong ví dụ bạn đã đưa ra vì bạn đảm bảo rằng toàn bộ mảng sẽ được lấp đầy với các khối bạn tạo ra.


2

Tôi muốn đề nghị xác định hình dạng đầu tiên. Sau đó lặp qua nó để chèn giá trị.

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

array([[ 0.,  0.],
       [ 1.,  1.],
       [ 2.,  2.],
       [ 3.,  3.],
       [ 4.,  4.],
       [ 5.,  5.]])

1

Có lẽ một cái gì đó như thế này sẽ phù hợp với nhu cầu của bạn ..

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

Cái nào tạo ra đầu ra sau

[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.