web-dev-qa-db-ja.com

空のNumPy配列への追加に失敗しました

Appendを使用して空の(np.emptyではなく!)配列に値を入力しようとしていますが、エラーが発生します:

私のコードは次のとおりです。

import numpy as np
result=np.asarray([np.asarray([]),np.asarray([])])
result[0]=np.append([result[0]],[1,2])

そして私は得ています:

ValueError: could not broadcast input array from shape (2) into shape (0)
30
Cupitor

_numpy.append_は、Pythonのlist.appendとはかなり異なります。私はそれがnumpyに新しいプログラマーを何人か投げ捨てたことを知っています。 _numpy.append_は連結に似ており、新しい配列を作成し、古い配列の値と追加する新しい値で埋めます。例えば:

_import numpy

old = numpy.array([1, 2, 3, 4])
new = numpy.append(old, 5)
print old
# [1, 2, 3, 4]
print new
# [1, 2, 3, 4, 5]
new = numpy.append(new, [6, 7])
print new
# [1, 2, 3, 4, 5, 6, 7]
_

私はあなたが次のようなことをすることであなたの目標を達成できるかもしれないと思う:

_result = numpy.zeros((10,))
result[0:2] = [1, 2]

# Or
result = numpy.zeros((10, 2))
result[0, :] = [1, 2]
_

更新:

ループを使用してnumpy配列を作成する必要があり、配列の最終サイズが事前にわからない場合は、次のようなことができます。

_import numpy as np

a = np.array([0., 1.])
b = np.array([2., 3.])

temp = []
while True:
    rnd = random.randint(0, 100)
    if rnd > 50:
        temp.append(a)
    else:
        temp.append(b)
    if rnd == 0:
         break

 result = np.array(temp)
_

私の例では、結果は(N、2)配列になります。ここで、Nはループの実行回数ですが、必要に応じて調整できます。

新しいアップデート

表示されているエラーは、型とは関係ありません。連結しようとしているnumpy配列の形状に関係しています。 np.append(a, b)を行う場合、abの形状が一致する必要があります。 (2、n)と(n、)を追加すると、(3、n)配列が得られます。コードは(1、0)を(2、)に追加しようとしています。これらの形状は一致しないため、エラーが発生します。

35
Bi Rico

私は質問を間違って理解するかもしれませんが、特定の形状の配列を宣言したいが、内部に何もない場合、以下が役立つかもしれません:

空の配列を初期化:

>>> a = np.zeros((0,3)) #or np.empty((0,3)) or np.array([]).reshape(0,3)
>>> a
array([], shape=(0, 3), dtype=float64)

これで、この配列を使用して、類似の形状の行を追加できます。 numpy配列は不変であるため、反復ごとに新しい配列が作成されることに注意してください。

>>> for i in range(3):
...     a = np.vstack([a, [i,i,i]])
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

np.vstackとnp.hstackはnumpy配列を結合するための最も一般的な方法ですが、Matlabから来た場合はnp.r_とnp.c_が好きです:

1dを連結:

>>> a = np.zeros(0)
>>> for i in range(3):
...     a = np.r_[a, [i, i, i]]
...
>>> a
array([ 0.,  0.,  0.,  1.,  1.,  1.,  2.,  2.,  2.])

行の連結:

>>> a = np.zeros((0,3))
>>> for i in range(3):
...     a = np.r_[a, [[i,i,i]]]
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

列の連結:

>>> a = np.zeros((3,0))
>>> for i in range(3):
...     a = np.c_[a, [[i],[i],[i]]]
...
>>> a
array([[ 0.,  1.,  2.],
       [ 0.,  1.,  2.],
       [ 0.,  1.,  2.]])
67
Simon Streicher

このエラーは、形状(0、)のオブジェクトを形状(2)のオブジェクトとして定義しようとしているという事実から発生します。 result [0]と等しくなるように強制せずに必要なものを追加する場合、問題はありません。

b = np.append([result[0]], [1,2])

しかし、result [0] = bを定義すると、異なる形状のオブジェクトを同一視していることになり、これを行うことはできません。あなたは何をしようとしているのですか?

4
Alejandro

Ipythonでコードを実行した結果は次のとおりです。 resultは_(2,0)_配列、2行、0列、0要素であることに注意してください。 appendは_(2,)_配列を生成します。 _result[0]_は_(0,)_配列です。エラーメッセージは、その2アイテムの配列をサイズ0のスロットに割り当てようとしていることに関係しています。 resultは_dtype=float64_であるため、その要素に割り当てることができるのはスカラーのみです。

_In [65]: result=np.asarray([np.asarray([]),np.asarray([])])

In [66]: result
Out[66]: array([], shape=(2, 0), dtype=float64)

In [67]: result[0]
Out[67]: array([], dtype=float64)

In [68]: np.append(result[0],[1,2])
Out[68]: array([ 1.,  2.])
_

_np.array_はPythonリストではありません。配列のすべての要素は同じタイプです(dtypeで指定されている)。また、resultは配列の配列ではありません。

結果は次のように構築することもできます。

_ll = [[],[]]
result = np.array(ll)
_

ながら

_ll[0] = [1,2]
# ll = [[1,2],[]]
_

結果についても同じではありません。

np.zeros((2,0))resultを生成します。

実際、resultには別の癖があります。

_result[0] = 1
_

resultの値は変更しません。割り当てを受け入れますが、列が0なので、_1_を置く場所がありません。この割り当ては、np.zeros((2,1))として作成された結果で機能します。しかし、それでもリストを受け入れることはできません。

ただし、resultに2つの列がある場合、2つの要素のリストをその行の1つに割り当てることができます。

_result = np.zeros((2,2))
result[0] # == [0,0]
result[0] = [1,2]
_

result操作の後、appendを正確にどのように表示しますか?

3
hpaulj

numpy.append は、新しい値を追加する前に常に配列をコピーします。コードは次のコードと同等です。

import numpy as np
result = np.zeros((2,0))
new_result = np.append([result[0]],[1,2])
result[0] = new_result # ERROR: has shape (2,0), new_result has shape (2,)

おそらくこれを行うつもりですか?

import numpy as np
result = np.zeros((2,0))
result = np.append([result[0]],[1,2])
2
Stuart Berg

SOスレッド ' 2つの配列要素を乗算します。1つの配列には要素として配列があります 'には、配列から配列を構築する例があります。サブ配列が同じサイズの場合、numpyは2次元配列を作成します。ただし、長さが異なる場合は、dtype=objectで配列が作成され、サブ配列はそのアイデンティティを保持します。

それに続いて、次のようなことができます。

In [5]: result=np.array([np.zeros((1)),np.zeros((2))])

In [6]: result
Out[6]: array([array([ 0.]), array([ 0.,  0.])], dtype=object)

In [7]: np.append([result[0]],[1,2])
Out[7]: array([ 0.,  1.,  2.])

In [8]: result[0]
Out[8]: array([ 0.])

In [9]: result[0]=np.append([result[0]],[1,2])

In [10]: result
Out[10]: array([array([ 0.,  1.,  2.]), array([ 0.,  0.])], dtype=object)

ただし、これが純粋なPythonリストまたはリストよりも優れていることはわかりません。2D配列のようには機能しません。たとえば、result[0][1]ではなくresult[0,1]を使用する必要があります。サブ配列はすべて同じ長さなので、np.array(result.tolist())を使用して2D配列を生成する必要があります。

1
hpaulj