Làm thế nào để thêm một hàng mới vào một mảng numpy trống


158

Sử dụng mảng Python tiêu chuẩn, tôi có thể làm như sau:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
# arr is now [[1,2,3],[4,5,6]]

Tuy nhiên, tôi không thể làm điều tương tự trong numpy. Ví dụ:

arr = np.array([])
arr = np.append(arr, np.array([1,2,3]))
arr = np.append(arr, np.array([4,5,6]))
# arr is now [1,2,3,4,5,6]

Tôi cũng đã xem xét vstack, nhưng khi tôi sử dụng vstacktrên một mảng trống, tôi nhận được:

ValueError: all the input array dimensions except for the concatenation axis must match exactly

Vì vậy, làm thế nào để tôi thêm một hàng mới vào một mảng trống trong numpy?


1
Nếu nó trống, tại sao phải bận tâm? Chỉ cần bắt đầu từ một mảng chỉ giữ hàng đầu tiên.
jonrsharpe

10
Tôi chỉ muốn biết liệu có thể nối vào một mảng numpy trống không. Đôi khi, việc viết mã như thế này sẽ tốt hơn vì các thao tác chắp thêm nằm trong một vòng lặp.
Tony Stark

5
Nhường chỗ các mảng NumPy công việc, bạn là tốt hơn nhiều xây dựng một mảng trống rỗng sau đó đưa dữ liệu trong, ví dụ: Xem stackoverflow.com/questions/568962/...
jonrsharpe

Câu trả lời:


227

Cách để "bắt đầu" mảng mà bạn muốn là:

arr = np.empty((0,3), int)

Đó là một mảng trống nhưng nó có chiều hướng thích hợp.

>>> arr
array([], shape=(0, 3), dtype=int64)

Sau đó, hãy chắc chắn để nối dọc theo trục 0:

arr = np.append(arr, np.array([[1,2,3]]), axis=0)
arr = np.append(arr, np.array([[4,5,6]]), axis=0)

Nhưng, @jonrsharpe đã đúng. Trong thực tế, nếu bạn sẽ nối thêm vào một vòng lặp, việc nối vào danh sách như trong ví dụ đầu tiên của bạn sẽ nhanh hơn nhiều, sau đó chuyển đổi thành một mảng numpy, vì bạn thực sự không sử dụng numpy như dự định trong vòng lặp:

In [210]: %%timeit
   .....: l = []
   .....: for i in xrange(1000):
   .....:     l.append([3*i+1,3*i+2,3*i+3])
   .....: l = np.asarray(l)
   .....: 
1000 loops, best of 3: 1.18 ms per loop

In [211]: %%timeit
   .....: a = np.empty((0,3), int)
   .....: for i in xrange(1000):
   .....:     a = np.append(a, 3*i+np.array([[1,2,3]]), 0)
   .....: 
100 loops, best of 3: 18.5 ms per loop

In [214]: np.allclose(a, l)
Out[214]: True

Cách thức numpythonic để làm điều đó phụ thuộc vào ứng dụng của bạn, nhưng nó sẽ giống như:

In [220]: timeit n = np.arange(1,3001).reshape(1000,3)
100000 loops, best of 3: 5.93 µs per loop

In [221]: np.allclose(a, n)
Out[221]: True

Nếu tôi phải làm điều này 10 ^ 5 hoặc 10 ^ 6 lần thì sao? có vẻ như cả hai phương pháp này đều không giữ được. Bất kì lời đề nghị nào?
Rho Phi

@Roberto, thường có một số cách để xác định kích thước hoặc hình dạng (ít nhất, các giá trị sẽ được ưu tiên hơn) của mảng trước. Bạn có nghĩ rằng bạn có thể làm điều đó? Việc áp dụng phải thực sự là một hoặc hai lần hoạt động.
askewchan

đôi khi bạn không thể đoán được kích thước, đó là cuộc sống. Tuy nhiên, bạn có thể phân bổ một mảng đủ lớn và đưa ra các giá trị cho các khung nhìn của nó. Mặc dù vậy, tôi không thích nó, bởi vì có những giá trị không mong muốn mà người ta phải tìm cách "che dấu". Ý tưởng về mặt nạ này thực sự không phù hợp với sở thích của tôi.
Rho Phi

Không cần phải đắp mặt nạ, chỉ cần cắt lát! a = a[:N] Mặc dù tôi tin tưởng mạnh mẽ rằng bạn nên tìm cách để vector hóa nó (đăng câu hỏi mới với thông tin cụ thể của bạn nếu bạn cần trợ giúp) hoặc chỉ sử dụng danh sách cho đến khi vòng lặp kết thúc.
askewchan

29

Đây là giải pháp của tôi:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
np_arr = np.array(arr)

Mảng kết quả có một loại đối tượng, không thể chấp nhận được trong một số trường hợp nhất định
zer0fool

26

Trong trường hợp này, bạn có thể muốn sử dụng các hàm np.hstack và np.vstack

arr = np.array([])
arr = np.hstack((arr, np.array([1,2,3])))
# arr is now [1,2,3]

arr = np.vstack((arr, np.array([4,5,6])))
# arr is now [[1,2,3],[4,5,6]]

Bạn cũng có thể sử dụng hàm np.concatenate.

Chúc mừng


7
Sẽ không hoạt động nếu mảng thứ hai có kích thước> = 2 như các mảng ((2, 2)). Nó xuất hiện với tôi không có cách nào để tránh các trường hợp ranh giới nếu bạn đang xây dựng các mảng từ trống bằng cách ghép.
Taozi

Không phải là một giải pháp tốt vì người ta cần kiểm tra kích thước mỗi lần.
SKR

1

sử dụng một định nghĩa dtype tùy chỉnh, điều làm việc cho tôi là:

import numpy

# define custom dtype
type1 = numpy.dtype([('freq', numpy.float64, 1), ('amplitude', numpy.float64, 1)])
# declare empty array, zero rows but one column
arr = numpy.empty([0,1],dtype=type1)
# store row data, maybe inside a loop
row = numpy.array([(0.0001, 0.002)], dtype=type1)
# append row to the main array
arr = numpy.row_stack((arr, row))
# print values stored in the row 0
print float(arr[0]['freq'])
print float(arr[0]['amplitude'])

1

Trong trường hợp thêm các hàng mới cho mảng trong vòng lặp, Gán mảng trực tiếp cho lần đầu tiên trong vòng lặp thay vì khởi tạo một mảng trống.

for i in range(0,len(0,100)):
    SOMECALCULATEDARRAY = .......
    if(i==0):
        finalArrayCollection = SOMECALCULATEDARRAY
    else:
        finalArrayCollection = np.vstack(finalArrayCollection,SOMECALCULATEDARRAY)

Điều này chủ yếu hữu ích khi hình dạng của mảng không xác định


0

Tôi muốn thực hiện một vòng lặp for, nhưng với phương thức của askewchan, nó không hoạt động tốt, vì vậy tôi đã sửa đổi nó.

x=np.empty((0,3))
y=np.array([1 2 3])
for i in ...
x = vstack((x,y))
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.