Menggabungkan dua array NumPy satu dimensi

266

Saya memiliki dua array satu dimensi sederhana di NumPy . Saya harus bisa menggabungkan mereka menggunakan numpy.concatenate . Tapi saya mendapatkan kesalahan ini untuk kode di bawah ini:

TypeError: hanya array panjang-1 yang dapat dikonversi ke skalar Python

Kode

import numpy
a = numpy.array([1, 2, 3])
b = numpy.array([5, 6])
numpy.concatenate(a, b)

Mengapa?

highBandWidth
sumber
Jika Anda ingin menggabungkan mereka (menjadi satu array) di sepanjang sumbu, gunakan np.concatenat(..., axis). Jika Anda ingin menumpuknya secara vertikal, gunakan np.vstack. Jika Anda ingin menumpuknya (ke dalam beberapa array) secara horizontal, gunakan np.hstack. (Jika Anda ingin menumpuknya dengan mendalam, yaitu dimensi ke-3, gunakan np.dstack). Perhatikan bahwa yang terakhir mirip dengan pandapd.concat
smci

Jawaban:

372

Garisnya harus:

numpy.concatenate([a,b])

Array yang ingin Anda gabungkan harus dilewatkan sebagai urutan, bukan sebagai argumen terpisah.

Dari dokumentasi NumPy :

numpy.concatenate((a1, a2, ...), axis=0)

Gabungkan barisan array secara bersamaan.

Itu mencoba menafsirkan Anda bsebagai parameter sumbu, itulah sebabnya ia mengeluh tidak bisa mengubahnya menjadi skalar.

Winston Ewert
sumber
1
Terima kasih! hanya ingin tahu - apa logika di balik ini?
user391339
8
@ user391339, bagaimana jika Anda ingin menggabungkan tiga array? Fungsi ini lebih berguna dalam mengambil urutan maka jika hanya butuh dua array.
Winston Ewert
@ WinstonEwert Dengan asumsi masalah ini bukan karena hardcoded ke dua argumen, Anda bisa menggunakannya seperti numpy.concatenate(a1, a2, a3)atau numpy.concatenate(*[a1, a2, a3])jika Anda suka. Cairan Python cukup sehingga perbedaannya terasa lebih kosmetik daripada substansial, tetapi bagus ketika API konsisten (misalnya jika semua fungsi numpy yang mengambil daftar argumen panjang variabel memerlukan urutan eksplisit).
Jim K.
@ Jim. Apa yang akan terjadi pada parameter sumbu?
Winston Ewert
1
Dengan asumsi hal-hal yang harus digabungkan adalah semua parameter posisi, Anda dapat menyimpan sumbu sebagai argumen kata kunci misalnya def concatx(*sequences, **kwargs)). Ini tidak ideal karena Anda sepertinya tidak dapat memberi nama kata kunci args secara eksplisit dalam tanda tangan dengan cara ini, tetapi ada beberapa solusi.
Jim K.
37

Ada beberapa kemungkinan untuk menggabungkan array 1D, misalnya,

numpy.r_[a, a],
numpy.stack([a, a]).reshape(-1),
numpy.hstack([a, a]),
numpy.concatenate([a, a])

Semua opsi tersebut sama-sama cepat untuk array besar; untuk yang kecil, concatenatememiliki sedikit keunggulan:

masukkan deskripsi gambar di sini

Plot dibuat dengan perfplot :

import numpy
import perfplot

perfplot.show(
    setup=lambda n: numpy.random.rand(n),
    kernels=[
        lambda a: numpy.r_[a, a],
        lambda a: numpy.stack([a, a]).reshape(-1),
        lambda a: numpy.hstack([a, a]),
        lambda a: numpy.concatenate([a, a]),
    ],
    labels=["r_", "stack+reshape", "hstack", "concatenate"],
    n_range=[2 ** k for k in range(19)],
    xlabel="len(a)",
)
Nico Schlömer
sumber
9
Alternatif semua digunakan np.concatenate. Mereka hanya memijat daftar input dengan berbagai cara sebelumnya. np.stackmisalnya menambahkan dimensi ekstra ke semua array input. Lihatlah kode sumber mereka. Hanya concatenatedikompilasi.
hpaulj
1
Hanya untuk menambahkan komentar @hpaulj - waktu semua konvergen ketika ukuran array bertambah karena np.concatenatemembuat salinan input. Memori dan biaya waktu ini lebih besar daripada waktu yang dihabiskan untuk 'memijat' input.
n1k31t4
31

Parameter pertama yang concatenateseharusnya menjadi urutan array untuk digabungkan:

numpy.concatenate((a,b)) # Note the extra parentheses.
Gabe
sumber
10

Alternatif lain untuk menggunakan bentuk singkat "concatenate" yang bisa berupa "r _ [...]" atau "c _ [...]" seperti yang ditunjukkan pada contoh kode di bawah ini (lihat http://wiki.scipy.org / NumPy_for_Matlab_Users untuk informasi tambahan):

%pylab
vector_a = r_[0.:10.] #short form of "arange"
vector_b = array([1,1,1,1])
vector_c = r_[vector_a,vector_b]
print vector_a
print vector_b
print vector_c, '\n\n'

a = ones((3,4))*4
print a, '\n'
c = array([1,1,1])
b = c_[a,c]
print b, '\n\n'

a = ones((4,3))*4
print a, '\n'
c = array([[1,1,1]])
b = r_[a,c]
print b

print type(vector_b)

Yang mengakibatkan:

[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]
[1 1 1 1]
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.  1.  1.  1.  1.] 


[[ 4.  4.  4.  4.]
 [ 4.  4.  4.  4.]
 [ 4.  4.  4.  4.]] 

[[ 4.  4.  4.  4.  1.]
 [ 4.  4.  4.  4.  1.]
 [ 4.  4.  4.  4.  1.]] 


[[ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]] 

[[ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 1.  1.  1.]]
Semjon Mössinger
sumber
2
vector_b = [1,1,1,1] #short form of "array", ini sama sekali tidak benar. vector_b akan menjadi tipe daftar Python standar. Namun Numpy cukup pandai menerima urutan alih-alih memaksa semua input menjadi tipe numpy.array.
Hannes Ovrén
2
Anda benar - saya salah. Saya memperbaiki kode sumber saya dan hasilnya.
Semjon Mössinger
0

Berikut adalah lebih pendekatan untuk melakukan hal ini dengan menggunakan numpy.ravel(), numpy.array(), memanfaatkan fakta bahwa 1D array dapat dibongkar menjadi elemen polos:

# we'll utilize the concept of unpacking
In [15]: (*a, *b)
Out[15]: (1, 2, 3, 5, 6)

# using `numpy.ravel()`
In [14]: np.ravel((*a, *b))
Out[14]: array([1, 2, 3, 5, 6])

# wrap the unpacked elements in `numpy.array()`
In [16]: np.array((*a, *b))
Out[16]: array([1, 2, 3, 5, 6])
kmario23
sumber
0

Beberapa fakta lagi dari numpy docs :

Dengan sintaks sebagai numpy.concatenate((a1, a2, ...), axis=0, out=None)

axis = 0 untuk concatenation baris-bijaksana axis = 1 untuk concatenation kolom-bijaksana

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6]])

# Appending below last row
>>> np.concatenate((a, b), axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])

# Appending after last column
>>> np.concatenate((a, b.T), axis=1)    # Notice the transpose
array([[1, 2, 5],
       [3, 4, 6]])

# Flattening the final array
>>> np.concatenate((a, b), axis=None)
array([1, 2, 3, 4, 5, 6])

Saya harap ini membantu!

Pe Dro
sumber