İki adet tek boyutlu NumPy dizisini birleştirme


266

NumPy'de iki basit tek boyutlu dizim var . Numpy.concatenate kullanarak bunları birleştirebilmeliyim . Ancak aşağıdaki kod için bu hatayı alıyorum:

TypeError: yalnızca uzunluk-1 dizileri Python skalerlerine dönüştürülebilir

kod

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

Neden?


Bunları bir eksen boyunca (tek bir diziye) birleştirmek istiyorsanız , kullanın np.concatenat(..., axis). Bunları dikey olarak istiflemek istiyorsanız, tuşunu kullanın np.vstack. Bunları yatay olarak istiflemek istiyorsanız (birden çok diziye) kullanın np.hstack. (Derinlik bakımından istiflemek istiyorsanız, örneğin 3. boyutta kullanın np.dstack). İkincisinin pandalara benzer olduğunu unutmayınpd.concat
smci

Yanıtlar:


372

Çizgi şöyle olmalıdır:

numpy.concatenate([a,b])

Birleştirmek istediğiniz dizilerin ayrı bağımsız değişkenler olarak değil, bir dizi olarak iletilmesi gerekir.

Gönderen NumPy belgelerinde :

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

Bir dizi diziyi birleştirin.

Senin beksen parametresi olarak yorumlamaya çalışıyordu , bu yüzden onu skaler hale getiremediğinden şikayet etti.


1
Teşekkürler! sadece merak ediyorum - bunun arkasındaki mantık nedir?
user391339

8
@ user391339, üç diziyi birleştirmek isterseniz ne olur? İşlev, bir dizi almakta, sadece iki dizi aldıysa daha kullanışlıdır.
Winston Ewert

@WinstonEwert Sorunun iki argümanla kodlanması olmadığı varsayılırsa, bunu istediğiniz gibi numpy.concatenate(a1, a2, a3)veya numpy.concatenate(*[a1, a2, a3])isterseniz kullanabilirsiniz. Python'un farkı, farkın kendisinden daha fazla kozmetik hissetmesine neden olacak kadar akışkan olmasına rağmen, API tutarlı olduğunda iyidir (örneğin, değişken uzunluklu argüman listelerini alan tüm numpy işlevleri açık diziler gerektiriyorsa).
Jim K.

@JimK. Axis parametresine ne olur?
Winston Ewert

1
Birleştirilecek şeylerin tüm konum parametreleri olduğunu varsayarsak, ekseni bir anahtar kelime argümanı olarak tutabilirsiniz def concatx(*sequences, **kwargs). İdeal değil çünkü args anahtar sözcüğünü imzada açıkça bu şekilde adlandıramazsınız, ancak geçici çözümler var.
Jim K.

37

1D dizilerini birleştirmek için çeşitli olasılıklar vardır, ör.

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

Tüm bu seçenekler büyük diziler için eşit derecede hızlıdır; küçük olanlar concatenateiçin hafif bir kenarı vardır:

resim açıklamasını buraya girin

Arsa perfplot ile oluşturuldu :

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)",
)

9
Tüm alternatifler kullanılır np.concatenate. Giriş listesine sadece çeşitli şekillerde masaj yaparlar. np.stackörneğin, tüm giriş dizilerine fazladan bir boyut ekler. Kaynak kodlarına bakın. Sadece concatenatederlenir.
hpaulj

1
Sadece @hpaulj 'ın yorumuna eklemek için - dizilerin boyutu büyüdükçe tüm zamanlar yakınlaşır, çünkü np.concatenategirdilerin kopyalarını yapar. Bu bellek ve zaman maliyeti, girdiye 'masaj yapmak' için harcanan süreden ağır basar.
n1k31t4

31

İlk parametrenin concatenatekendisi , birleştirilecek diziler dizisi olmalıdır :

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

10

Alternatif olarak, aşağıdaki örnek kodda gösterildiği gibi "r _ [...]" veya "c _ [...]" olan kısa "bitiş" biçimini kullanmak isteyebilirsiniz (bkz. Http://wiki.scipy.org / Ek bilgi için NumPy_for_Matlab_Users ):

%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)

Sonuç:

[ 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.]]

2
vector_b = [1,1,1,1] #short form of "array", bu doğru değil. vector_b standart bir Python liste türü olacaktır. Ancak Numpy, tüm girişleri numpy.array tipi olmaya zorlamak yerine dizileri kabul etmekte oldukça iyidir.
Hannes Ovrén

2
Haklısın - yanılmışım. Sonuç olarak kaynak kodumu da düzelttim.
Semjon Mössinger

0

İşte daha fazladır kullanarak bunu yaklaşımları numpy.ravel(), numpy.array(), gerçeği kullanan 1D diziler düz elemanlar içine çözdükten olabilir:

# 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])

0

Numpy dokümanlarından bazı gerçekler :

Sözdizimi ile numpy.concatenate((a1, a2, ...), axis=0, out=None)

eksen = satır bazında birleştirme için eksen = 1 sütun bazında birleştirme için

>>> 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])

Umut ediyorum bu yardım eder !

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.