8

さて、numpy の構造化配列に関するチュートリアルを行った後、いくつかの簡単な例を作成できます。

from numpy import array, ones
names=['scalar', '1d-array', '2d-array']
formats=['float64', '(3,)float64', '(2,2)float64']
my_dtype = dict(names=names, formats=formats)
struct_array1 = ones(1, dtype=my_dtype)
struct_array2 = array([(42., [0., 1., 2.], [[5., 6.],[4., 3.]])], dtype=my_dtype)

(私の意図した使用例では、3 つ以上のエントリがあり、非常に長い 1 次元配列が使用されます。) したがって、基本的な計算を実行しようとするまでは、すべてうまくいきます。次のすべてでエラーが発生します。

struct_array1 + struct_array2
struct_array1 * struct_array2
1.0 + struct_array1
2.0 * struct_array2

どうやら、単純な演算子 (+、-、​​、/) は、最も単純な構造化配列でもサポートされていません。または、何か不足していますか?他のパッケージを検討する必要がありますか (パンダとは言わないでください。これは完全にやり過ぎです)。これは当然の能力のように思えるので、少し唖然とします。しかし、ネット上でこれについてのおしゃべりを見つけるのは難しい. これは構造化配列の有用性を著しく制限していませんか? 辞書にパックされた配列ではなく、構造配列を使用するのはなぜですか? これが扱いにくいかもしれない技術的な理由はありますか? あるいは、オーバーロードという骨の折れる作業を実行することが正しい解決策である場合、操作を高速に保ちながらそれをどのように行うのでしょうか?

4

3 に答える 3

3

配列全体を操作する別の方法は、ドキュメントで説明されている「ユニオン」dtype を使用することです。あなたの例では、「ユニオン」フィールドを追加し、重複する「オフセット」を指定することで、dtype を拡張できます。

from numpy import array, ones, zeros

names=['scalar', '1d-array', '2d-array', 'union']
formats=['float64', '(3,)float64', '(2,2)float64', '(8,)float64']
offsets=[0, 8, 32, 0]
my_dtype = dict(names=names, formats=formats, offsets=offsets)
struct_array3=zeros((4,), dtype=my_dtype)

['union'](n,8)すべてのデータに配列としてアクセスできるようになりました

struct_array3['union'] # == struct_array3.view('(8,)f8')
struct_array3['union'].shape  # (4,8)

「ユニオン」またはその他のフィールドで操作できます。

struct_array3['union'] += 2
struct_array3['scalar']= 1

「ユニオン」フィールドは、 などの別の互換性のある形状である可能性があり'(2,4)float64'ます。このような配列の「行」は次のようになります。

array([ (3.0, [0.0, 0.0, 0.0], [[2.0, 2.0], [0.0, 0.0]], 
      [[3.0, 0.0, 0.0, 0.0], [2.0, 2.0, 0.0, 0.0]])], 
      dtype={'names':['scalar','1d-array','2d-array','union'], 
             'formats':['<f8',('<f8', (3,)),('<f8', (2, 2)),('<f8', (2, 4))], 
             'offsets':[0,8,32,0], 
             'itemsize':64})
于 2014-10-24T16:23:19.710 に答える
0

さて、さらに調査した後、私は答えに出くわしました。(hpaulj のせいではありません - 質問はそれほどうまくいきませんでした。) しかし、他の誰かが同様の欲求不満を持っている場合に備えて投稿したかったのです。

答えは、ndarray.view の numpy ドキュメントから得られます。彼らは具体的に、「計算で使用できるように構造化配列のビューを[作成]する」例を提供しています。

そのため、サンプルの構造化配列を操作できないことに不満を感じていました。結局のところ、構造化された配列は単に浮動小数点数の集まりとして「見えます」! 結局、必要なのは、「ビュー」を使用してこの抽象化を numpy に通知することだけでした。問題のエラーは、次を使用して回避できます。

( struct_array1.view(dtype='float64') + struct_array2.view(dtype='float64') ).view(dtype=my_dtype)
( struct_array1.view(dtype='float64') + struct_array2.view(dtype='float64') ).view(dtype=my_dtype)
( 1.0 + struct_array2.view(dtype='float64') ).view(dtype=my_dtype)
( 2.0 * struct_array2.view(dtype='float64') ).view(dtype=my_dtype)

これは望むほどエレガントではありませんが、少なくとも numpy にはその機能があります。

于 2014-10-17T00:49:27.197 に答える