Cara menambahkan baris baru ke array numpy kosong

158

Menggunakan array Python standar, saya bisa melakukan hal berikut:

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

Namun, saya tidak bisa melakukan hal yang sama di numpy. Sebagai contoh:

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]

Saya juga melihat ke dalam vstack, tetapi ketika saya gunakan vstackpada array kosong, saya mendapatkan:

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

Jadi bagaimana cara menambahkan baris baru ke array kosong di numpy?

Tony Stark
sumber
1
Jika kosong, mengapa repot-repot? Mulai saja dari array yang hanya memegang baris pertama.
jonrsharpe
10
Saya hanya ingin tahu apakah mungkin untuk menambahkan array numpy kosong. Terkadang lebih bersih menulis kode seperti ini karena operasi append dalam satu lingkaran.
Tony Stark
5
Mengingat cara kerja array numpy, Anda jauh lebih baik membangun array kosong kemudian memasukkan data, misalnya Lihat stackoverflow.com/questions/568962/…
jonrsharpe

Jawaban:

227

Cara untuk "memulai" array yang Anda inginkan adalah:

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

Yang merupakan array kosong tetapi memiliki dimensi yang tepat.

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

Maka pastikan untuk menambahkan sepanjang sumbu 0:

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

Tapi, @jonrsharpe benar. Bahkan, jika Anda akan menambahkan dalam satu lingkaran, itu akan jauh lebih cepat untuk menambahkan ke daftar seperti pada contoh pertama Anda, kemudian konversikan ke array numpy pada akhirnya, karena Anda benar-benar tidak menggunakan numpy sebagai dimaksudkan selama loop:

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

Cara numpythonic untuk melakukannya tergantung pada aplikasi Anda, tetapi itu akan lebih seperti:

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
askewchan
sumber
bagaimana jika saya harus melakukan ini 10 ^ 5 atau 10 ^ 6 kali? tampaknya tidak satu pun dari metode ini akan berlaku. ada saran?
Rho Phi
@Roberto, biasanya ada beberapa cara untuk menentukan ukuran atau bentuk (paling tidak, nilai akan lebih disukai) dari array terlebih dahulu. Apakah Anda pikir Anda bisa melakukan itu? Menambahkan harus benar-benar operasi satu atau dua kali.
askewchan
kadang-kadang Anda tidak bisa menebak dimensi, itu hidup. Namun Anda dapat mengalokasikan array yang cukup besar dan memberi nilai pada view-nya. Saya tidak suka, karena ada nilai-nilai yang tidak diinginkan yang harus ditemukan orang untuk "menutupi". Ide masking ini benar-benar tidak sesuai dengan seleraku.
Rho Phi
Tidak perlu topeng, cukup iris! a = a[:N] Meskipun saya sangat percaya Anda harus menemukan cara untuk membuat vektor itu (memposting pertanyaan baru dengan spesifik Anda jika Anda memerlukan bantuan) atau hanya menggunakan daftar sampai loop selesai.
askewchan
29

Ini solusinya:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
np_arr = np.array(arr)
just4fun
sumber
Array yang dihasilkan memiliki tipe objek, yang tidak dapat diterima dalam kasus-kasus tertentu
zer0fool
26

Dalam hal ini Anda mungkin ingin menggunakan fungsi np.hstack dan 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]]

Anda juga dapat menggunakan fungsi np.concatenate.

Bersulang

mrcl
sumber
7
Tidak akan berfungsi jika array kedua memiliki dimensi> = 2 yang mirip ((2, 2)). Sepertinya saya tidak ada cara untuk menghindari kasus batas jika Anda membangun array dari kosong oleh penggabungan.
Taozi
Bukan solusi yang baik karena kita perlu memeriksa dimensi setiap waktu.
SKR
1

menggunakan definisi tipe kustom, yang berhasil bagi saya adalah:

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'])
boclodoa
sumber
1

Dalam hal menambahkan baris baru untuk array dalam loop, Tetapkan array secara langsung untuk firsttime dalam loop daripada menginisialisasi array kosong.

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

Ini terutama berguna ketika bentuk array tidak diketahui

Rajesh_Saladi
sumber
0

Saya ingin melakukan for for, namun dengan metode askewchan itu tidak berfungsi dengan baik, jadi saya telah memodifikasinya.

x=np.empty((0,3))
y=np.array([1 2 3])
for i in ...
x = vstack((x,y))
Qingdong Wang
sumber