17

同じ形状の 2 つの入力配列 x と y があります。関数を介して一致するインデックスで各要素を実行し、それらのインデックスで結果を 3 番目の配列 z に格納する必要があります。これを達成するための最もpythonicな方法は何ですか? 現在、4 つの 4 ループがあります。もっと簡単な方法があるはずです。

x = [[2, 2, 2],
     [2, 2, 2],
     [2, 2, 2]]

y = [[3, 3, 3],
     [3, 3, 3],
     [3, 3, 1]]

def elementwise_function(element_1,element_2):
    return (element_1 + element_2)

z = [[5, 5, 5],
     [5, 5, 5],
     [5, 5, 3]]

私の関数は個々のデータペアでしか機能しないため、混乱しています。x 配列と y 配列を単純に関数に渡すことはできません。

4

3 に答える 3

21

「より簡単な方法」の 1 つは、 を使用して NumPy 対応関数を作成することnumpy.vectorizeです。「ufunc」は、要素ごとの関数の NumPy 用語です (こちらのドキュメントを参照してください)。Using を使用numpy.vectorizeすると、要素ごとの関数を使用して独自の ufunc を作成できます。これは、他の NumPy ufunc (標準の追加など) と同じように機能します。ufunc は配列を受け入れ、関数を各ペアに適用します。要素、標準の NumPy 関数などと同じように、配列形状のブロードキャストを行います。ドキュメント ページには、役立つ使用例がいくつかあります。

In [1]: import numpy as np
   ...: def myfunc(a, b):
   ...:     "Return 1 if a>b, otherwise return 0"
   ...:     if a > b:
   ...:         return 1
   ...:     else:
   ...:         return 0
   ...: vfunc = np.vectorize(myfunc)
   ...: 

In [2]: vfunc([1, 2, 3, 4], [4, 3, 2, 1])
   ...: 
Out[2]: array([0, 0, 1, 1])
In [3]: vfunc([1, 2, 3, 4], 2)
   ...: 
Out[3]: array([0, 0, 1, 1])
于 2012-11-25T23:45:10.353 に答える
4

(単純な python について話していると思いますがlist、 ではありませんnumpy.array

再帰は常に私たちの生活を楽にします:

def operate_on_Narray(A, B, function):
    try:
        return [operate_on_Narray(a, b, function) for a, b in zip(A, B)]
    except TypeError as e:
        # Not iterable
        return function(A, B)

使用法:

>>> x = [[2, 2, 2],
...      [2, 2, 2],
...      [2, 2, 2]]
>>> 
>>> y = [[3, 3, 3],
...      [3, 3, 3],
...      [3, 3, 1]]
>>> operate_on_Narray(x, y, lambda a, b: a+b)
[[5, 5, 5], [5, 5, 5], [5, 5, 3]]

他の種類の次元配列でも機能します。

>>> operate_on_Narray([1, 2, 3], [4, 5, 6], lambda a, b: a*b)
[4, 10, 18]
于 2012-11-25T23:48:54.530 に答える
3

Python 2.7.3 インタープリター セッションからの次のトランスクリプトは、組み込み関数mapを使用して要素ごとの操作を 2D マトリックス要素に適用する方法を示しています。(注:operator.addelementwise_function問題の指定と同等であり、 の 2 番目の使用におけるラムダ式とも同等ですapplier。)

>>> import operator
>>> def applier(a, b, op):
...     return map(lambda ro: map(op, ro[0], ro[1]), zip(a,b))
... 
>>> applier(x, y, operator.add)
[[5, 5, 2], [5, 4, 5], [6, 5, 5]]
>>> x; y
[[2, 2, 1], [2, 2, 2], [3, 2, 2]]
[[3, 3, 1], [3, 2, 3], [3, 3, 3]]
>>> applier(x, y, lambda p,q: p+q)
[[5, 5, 2], [5, 4, 5], [6, 5, 5]]
>>> applier(x, y, lambda p,q: p-q)
[[-1, -1, 0], [-1, 0, -1], [0, -1, -1]]
>>> applier(x, y, lambda p,q: p*q)
[[6, 6, 1], [6, 4, 6], [9, 6, 6]]

上記の x、y は次のようになっていることに注意してください。

x=[[2, 2, 1], [2, 2, 2], [3, 2, 2]]
y=[[3, 3, 1], [3, 2, 3], [3, 3, 3]]

前述のように、上記のトランスクリプトは Python 2.7.3 インタープリター セッションからのものです。このコードを Python 3 で実行すると、代わりにマップ オブジェクトが返されます。次のような関数を使用して、数値を確認できます。

def itemize(m):
    return [itemize(e) for e in m] if hasattr(m, '__iter__') else m

その機能を使用すると、ステートメント

itemize(applier(x, y, operator.add))

戻り値

[[5, 5, 2], [5, 4, 5], [6, 5, 5]]
于 2012-11-26T00:02:08.240 に答える