は、私は、次のnumpyの配列があるとします。委任呼び出し
arr = np.array(["a", "b", "c"], dtype=object)
今、私は任意の関数を実行するか、各要素上の任意のメソッドを呼び出します。たとえば、これらすべての要素の大文字を取得したいとします。
upp_arr = arr.upper()
または
upp_arr = str.upper(arr)
ショートバージョン:「論理的」に言えば、私はこのような何かをしたいのですが、私はどちらかは、上記の達成することができますか?
ロングバージョン: は、これは明らかに(個々の要素がない場合でも)upper
メソッドを持っていない配列を考慮し、仕事に行くされていない、またstr
ビルトインはnumpyの配列を処理する方法を知っています。配列を扱う方法を知っているstr.upper
のカスタムバージョンを構築したくないのです。それは、配列のユーザーが使用したい機能を事前に知っておく必要があるからです。
でも、私は
upp_arr = np.array([x.upper() for x in arr])
私はこれが好きではないような何かを行うことができます:今、私はarr
が実際にnumpyの配列であることを私のコードのユーザーに公開する必要があります。私は上記の2つの非機能的なソリューションのようなものを入手したい。
私はnp.ndarray
をサブクラス化によってこれを実現するために試みたが、name
はnp.ndarray
の属性でない場合、名前name
の要素の属性の配列を返すように__getattr__(self, name)
メソッドを上書きし、にその__call__
メソッドを上書き要素の配列コール `結果を返します:
import numpy as np
class MyArr(np.ndarray):
def __getattr__(self, name):
if hasattr(np.ndarray, name):
return getattr(np.ndarray, name)
arr = MyArr(self.shape, dtype=object)
arr[:] = [getattr(elem, name) for elem in self]
return arr
def __call__(self):
arr = MyArr(self.shape, dtype=self.dtype)
arr[:] = [elem() for elem in self]
return arr
arr = MyArr((3,), dtype=object)
arr[:] = ["a", "b", "c"]
arr.upper()
これは二つの問題があります。配列を構築することはお尻の痛みですが、(最初にそれをインスタンス化し、その後、値でそれを埋めるために持っている)と、私は、 f関数呼び出しは元の配列(dtype=self.dtype
部分)と同じdtypeです。この後者は、object
タイプの配列に固執すれば問題はありませんが、一般的になります。
どうすれば解決できますか?
コンストラクトと塗りつぶしに問題はありません。 'numpy'は常にそれを行います。 'vectorize'は一つの値を評価し、その結果を使ってreturn dtypeを設定します。時々それはSOの質問を引き起こす。 – hpaulj