2

これは、ND データを取得する方法です ( funcIRL はベクトル化できません)。

import numpy
import xarray
import itertools

xs = numpy.linspace(0, 10, 100)
ys = numpy.linspace(0, 0.1, 20)
zs = numpy.linspace(0, 5, 200)

def func(x, y, z):
    return x * y / z

vals = list(itertools.product(xs, ys, zs))
result = [func(x, y, z) for x, y, z in vals]

自分のしていることは単純化できると感じています。データを再形成せずにこれを入れたいと思いxarray.DataArrayます。しかし、これは私が今それを行う方法です:

arr = np.array(result).reshape(len(xs), len(ys), len(zs))
da = xarray.DataArray(arr, coords=[('x', xs), ('y', ys), ('z', zs)])

itertools.productこれは単純な例ですが、通常、 (並列に)をマッピングして取得した ~10D データを使用します。

私の質問: データを再形成せずに、 、、およびvalsの長さを使用および使用せずにこれを行うにはどうすればよいですか?xsyszs

あなたが何をするかと同様の方法で:

index = pandas.MultiIndex.from_tuples(vals, names=['x', 'y', 'z'])
df = pandas.DataFrame(result, columns=['result'], index=index)

編集: @hpauljの答えに触発されて、これが私がそれを解決した方法です、ありがとう!

import numpy
import xarray
import itertools

coords = dict(x=numpy.linspace(0, 10, 100),
              y=numpy.linspace(0, 0.1, 20),
              z=numpy.linspace(0, 5, 200))

def func(x, y, z):
    return x * y / z

result = [func(x, y, z) for x, y, z in itertools.product(*coords.values())]

xarray.DataArray(numpy.reshape(result, [len(i) for i in coords.values()]), coords=coords)

EDIT 2 この問題を参照してください: https://github.com/pydata/xarray/issues/1914

4

2 に答える 2

2

経験豊富なnumpyユーザーは、反復ステップの削除に集中する傾向があります。したがって、あなたのresult計算にズームインし、reshapeを些細なことと見なします。したがって、これまでの回答は、関数のブロードキャストと計算に焦点を当ててきました。

でも、あなたを本当に悩ませているのは、

reshape(len(xs), len(ys), len(zs))

そのような次元が 3 つだけでなく 10 ある場合、扱いにくくなる可能性があります。計算速度はさほど重要ではありませんが、len(..)10 回タイプするのに必要な労力です。あるいは、コードが醜く見えるかもしれません。

とにかく、ここにすべての入力をバイパスする方法があります。重要なのは、次元配列をリストに集めることです

In [495]: dims = [np.linspace(0,10,4), np.linspace(0,.1,3), np.linspace(0,5,5)]
In [496]: from itertools import product
In [497]: vals = list(product(*dims))
In [498]: len(vals)
Out[498]: 60
In [499]: result = [sum(ijk) for ijk in vals] # a simple func

len's次に、単純なリスト内包表記で を取得します。

In [501]: arr=np.array(result).reshape([len(i) for i in dims])
In [502]: arr.shape
Out[502]: (4, 3, 5)

もう 1 つの可能性は、linspaceパラメーターを最初にリストに入れることです。

In [504]: ldims=[4,3,5]
In [505]: ends=[10,.1,5]
In [506]: dims=[np.linspace(0,e,l) for e,l in zip(ends, ldims)]
In [507]: vals = list(product(*dims))
In [508]: result=[sum(ijk) for ijk in vals]
In [509]: arr=np.array(result).reshape(ldims)

reshapeそれ自体は高価な操作ではありません。通常、ビューを作成します。これは、配列で実行できる最も高速な処理の 1 つです。

@Divakar*np.meshgrid(*A)あなたの代わりに、彼の削除された回答でこの種の解決策を示唆しましたproduct(xs,ys)

ちなみに、私の答えにはxarrayどちらも含まれていません-そのパッケージがインストールされていないためです。arr長い 1 次元配列とは対照的に、その 3 次元形状を渡すときに何をしているのかを知っていると思います。タグ番号を見ると、 は 5k フォロワー、numpyは 23 ですxarray

パラメーターは、(名前の追加リストを使用して)xarray coordsから構築することもできます。dims

xarrayこの回答が気に入らない場合は、質問を閉じて、タグだけで新しい質問を開始することをお勧めします。そうすれば、多数のnumpyハエを引き付けることはありません。

于 2016-11-09T16:46:46.053 に答える