2つの1次元NumPy配列を連結する


266

NumPyに 2つの単純な1次元配列があります。numpy.concatenateを使用してそれらを連結できるはずです。しかし、以下のコードでこのエラーが発生します:

TypeError:長さ1の配列のみをPythonスカラーに変換できます

コード

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

どうして?


それらを軸に沿って(単一の配列に)連結する場合は、を使用しますnp.concatenat(..., axis)。縦に積み上げる場合は、を使用しますnp.vstack。それらを(複数の配列に)水平に積み重ねたい場合は、を使用しますnp.hstack。(それらを深さ方向にスタックする場合、つまり3次元にする場合は、を使用しますnp.dstack)。後者はパンダに似ていることに注意してくださいpd.concat
smci

回答:


372

行は次のようになります。

numpy.concatenate([a,b])

連結する配列は、個別の引数としてではなく、シーケンスとして渡す必要があります。

NumPyドキュメントから:

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

一連の配列を結合します。

あなたbを軸パラメータとして解釈しようとしたため、スカラーに変換できないと不満を漏らしました。


1
ありがとう!ただ好奇心が強い-これの背後にある論理は何ですか?
user391339

8
@ user391339、3つの配列を連結したい場合はどうなりますか?この関数は、2つの配列を取得する場合よりも、シーケンスを取得する場合に役立ちます。
Winston Ewert 2016

@WinstonEwert問題が2つの引数にハードコードされていることではないと想定すると、好きなように、numpy.concatenate(a1, a2, a3)またはnumpy.concatenate(*[a1, a2, a3])好みに応じて使用できます。Pythonは流動的であるため、違いは実質的なものよりも見た目が美しく感じられますが、APIが一貫している場合に適しています(たとえば、可変長引数リストを取るすべてのnumpy関数が明示的なシーケンスを必要とする場合)。
ジムK.16年

@JimK。軸パラメーターはどうなりますか?
Winston Ewert 2016

1
連結するものがすべて定位置パラメーターであると想定すると、軸をキーワード引数として保持できます(例:)def concatx(*sequences, **kwargs)。この方法では、シグネチャでキーワードargsに明示的に名前を付けることができないため、これは理想的ではありませんが、回避策はあります。
ジムK.

37

1D配列を連結する方法はいくつかあります。たとえば、

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

これらのオプションはすべて、大規模な配列に対しても同等に高速です。小さなもののためconcatenateに、わずかなエッジがあります:

ここに画像の説明を入力してください

プロットは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)",
)

9
選択肢はすべて使用しますnp.concatenate。事前にさまざまな方法で入力リストをマッサージするだけです。 np.stackたとえば、すべての入力配列に次元を追加します。彼らのソースコードを見てください。のみconcatenateコンパイルされます。
hpaulj

1
@hpauljのコメントに追加するだけです- np.concatenateは入力のコピーを作成するため、配列のサイズが大きくなるにつれてすべての時間が収束します。このメモリと時間のコストは、入力の「マッサージ」に費やされた時間を上回ります。
n1k31t4 2018年

31

への最初のパラメーターconcatenateは、それ自体が連結する一連の配列である必要があります。

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

10

以下のコード例に示されているように、 "r _ [...]"または "c _ [...]"のいずれかの短い形式の "concatenate"を使用することもできます(http://wiki.scipy.orgを参照) / 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)

その結果:

[ 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"、これは単に本当ではありません。vector_bは、標準のPythonリストタイプになります。ただし、Numpyは、すべての入力をnumpy.arrayタイプにするのではなく、シーケンスを受け入れるのが得意です。
HannesOvrén2013

2
あなたは正しい-私は間違っていた。ソースコードと結果を修正しました。
SemjonMössinger2013

0

ここでは、より使用してこれを行うためのアプローチですnumpy.ravel()numpy.array()1Dアレイはプレーンな要素にアンパックすることができるという事実を利用し、:

# 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 docsからいくつかの事実:

構文として numpy.concatenate((a1, a2, ...), axis=0, out=None)

軸= 0(行方向の連結の場合)軸= 1(列方向の連結の場合)

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

お役に立てば幸いです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.