0

行数が同じ2 つのNumPy配列がありますが、特定の列を追加したいと考えています。

私は次のことを試しました:

src_array[:, 3] += column_array_to_add[:, 0]

しかし、それは解釈さえしません。でこれを行う正しい方法は何NumPyですか? 整数と文字列の両方でできるようにしたいです。

編集:テスト用の短い自己完結型スクリプト

import numpy
src = numpy.array([["a", "b"], ["c", "d"], ["e", "f"]])
src2 = numpy.array([["x"], ["y"], ["z"]])

src[:, 1] += src2[:, 0]
print src
exit()

このスクリプトは次のエラーを返します。

src[:, 1] += src2[:, 0]
TypeError: unsupported operand type(s) for +=: 'numpy.ndarray' and 'numpy.ndarray'
4

2 に答える 2

5

このようなものは機能しますか?

import numpy as np

x = np.array([[1,2],[3,4]])

y = np.array([[5,6],[7,8]])

結果

>>> x
array([[1, 2],
       [3, 4]])
>>> y
array([[5, 6],
       [7, 8]])
>>> x[:,1] + y[:,1]
array([ 8, 12])
>>> x[:, 1] += y[:, 1] # using +=
>>> x[:, 1]
array([ 8, 12])

アップデート:

これはあなたのために働くはずだと思います:

src = np.array([["a", "b"], ["c", "d"], ["e", "f"]], dtype='|S8')
src2 = np.array([["x"], ["y"], ["z"]], dtype='|S8')

def add_columns(x, y):
    return [a + b for a,b in zip(x, y)]

def update_array(source_array, col_num, add_col):
    temp_col = add_columns(source_array[:, col_num], add_col)
    source_array[:, col_num] = temp_col  
    return source_array

結果:

>>> update_array(src, 1, src2[:,0])
array([['a', 'bx'],
       ['c', 'dy'],
       ['e', 'fz']], 
      dtype='|S8')
于 2012-12-06T01:43:37.260 に答える
0

この種のものをデバッグする必要がある場合は、より単純なステップに分割すると便利です。スライスが間違っている、互換性のない 2 つの配列型を追加する、2 つの型を追加するが結果を互換性のない型に貼り付けようとする ( +=when +is OK but =is not を使用)、または互換性のないデータ値を追加しますか? それらのいずれかが を発生させる可能性がTypeErrorあります。

一度にそれらを実行して、以下を確認してください。

スライス:

>>> src[:, 1]
array(['b', 'd', 'f'], dtype='|S1')
>>> src[:, 1] = ['x', 'y', 'z']
>>> src
>>> array([['a', 'x'], ['c', 'y'], ['e', 'z']], dtype='|S1')

それはいいです。追加するのはどうですか?

>>> src + src2
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.ndarray'

そのため、スライスなしで、+=デバッグがはるかに簡単になる、より複雑なケースと同じエラーが既に見つかりました。さらに簡単にしましょう。

>>> s1, s2 = np.array('a'), np.array('b')
>>> s1 + s2
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.ndarray'

したがって、2 つの 0D 配列を追加しても失敗します。それよりも簡単にすることはできません。

多分それはデータ型です。整数を使用するとどうなりますか?

>>> n1, n2 = np.array(1), np.array(2)
>>> n1 + n2
3

また、文字列の代わりに整数を使用して、元の例に戻ることができますが、それでも問題なく動作します。

>>> m1 = np.array([[1,2], [3,4], [5,6]])
>>> m2 = np.array([[7], [8], [9]])
>>> m1[:, 1] += m2[:, 0]
>>> array([[ 1,  9],
           [ 3, 12],
           [ 5, 15]])

これにより、問題がデータ型にあることが明らかになります。では、データ型は何ですか?配列を印刷して、numpyそれが何であるかを確認してください。

>>> src = numpy.array([["a", "b"], ["c", "d"], ["e", "f"]])
>>> src
array([['a', 'b'], ['c', 'd'], ['e', 'f']], dtype='|S1')

これは、ユーザー ガイドの「データ型'|S1'」セクションにある使いやすいデータ型の 1 つではありません。構造化配列のセクションで説明されているように、これは構造定義です。つまり、1 文字の固定長文字列です。

結果が 1 文字の固定長文字列ではないため、1 文字の固定長文字列を 2 つ追加することはできません。

これをそのまま機能させたい場合、簡単な解決策は、Python 文字列のままにしておくことです。

>>> src = numpy.array([["a", "b"], ["c", "d"], ["e", "f"]], dtype=object)
>>> src2 = numpy.array([["x"], ["y"], ["z"]], dtype=object)    
>>> src[:, 1] += src2[:, 0]

もうTypeError

または、明示的にsrcdtype を指定すると|S2numpyそれが許可され、2 番目の文字は空白になります。別のものを追加することは|S1できませんが、Python でループするか、複雑な修正方法を見つけnumpyてそれを行うことができます。いずれにせよ、numpyもちろん、通常の時間パフォーマンスの利点は得られませんが、パックされた固定サイズのセルを使用するスペース パフォーマンスの利点は得られます。

しかし、一歩下がって、ここから何を得ようとしているのかを尋ねてみてくださいnumpy。ここでの実際のより高いレベルの目標は何ですか? の利点のほとんどは、操作方法を知っているnumpy厳密な C/Fortran スタイルのデータ型を使用するnumpyことから得られます。それらを密にパックし、追加の逆参照なしで (および refcounting なしで) アクセスし、乗算からPythonなどの助けを借りずに印刷にコピーしますが、文字列操作はできません。文字列操作をベクトル化しようとしている場合は、間違ったライブラリを使用しています。numpy誰かが速いと言ったから使っているだけなら、それは多くの場合に当てはまりますが、今回はそうではありません。numpy他のコードがnumpyデータを処理しているために使用しているが、そうでない場合numpyそれを純粋な Python データに変換することを妨げるものは何もありません。

于 2012-12-06T18:54:43.900 に答える