私はあなたの反復的な方法は、このようなものであると想像:
In [204]: dd = {
...: 'distro': {0: 2.42, 3: 2.56},
...: 'constant': 4.55,
...: 'size': 10,
...: }
In [205]: dd
Out[205]: {'constant': 4.55, 'distro': {0: 2.42, 3: 2.56}, 'size': 10}
In [207]: x = np.zeros(dd['size'])
In [208]: x[:] = dd['constant']
In [210]: for i,v in dd['distro'].items():
...: x[i] = v
In [211]: x
Out[211]: array([ 2.42, 4.55, 4.55, 2.56, 4.55, 4.55, 4.55, 4.55, 4.55, 4.55])
x[:]
に代わる、x.fill(dd['constant'])
ですが、速度の大きな違いはないと思います。
ここで明示的に反復することなく、辞書から値を設定する方法です:
In [221]: ddvals = np.array(list(dd['distro'].items()),dtype='i,f')
In [222]: ddvals
Out[222]:
array([(0, 2.42000008), (3, 2.55999994)],
dtype=[('f0', '<i4'), ('f1', '<f4')])
In [223]: x[ddvals['f0']]=ddvals['f1']
In [224]: x
Out[224]:
array([ 2.42000008, 4.55 , 4.55 , 2.55999994, 4.55 ,
4.55 , 4.55 , 4.55 , 4.55 , 4.55 ])
または構造化された配列なし:
In [225]: vals = np.array(list(dd['distro'].items()))
In [226]: vals
Out[226]:
array([[ 0. , 2.42],
[ 3. , 2.56]])
In [227]: x[vals[:,0]] = vals[:,1]
...
IndexError: arrays used as indices must be of integer (or boolean) type
In [228]: x[vals[:,0].astype(int)] = vals[:,1]
In [229]: x
Out[229]: array([ 2.42, 4.55, 4.55, 2.56, 4.55, 4.55, 4.55, 4.55, 4.55, 4.55])
辞書items()
(またはPY3でlist(items())
は)のリストを与えますタプル。 Newer numpy
バージョンでは、floatをインデックスとして使用したくないため、整数キー値を保持するためにいくつかの手順を追加する必要があります。
これは最も単純であるかもしれない:
x[list(dd['distro'].keys())] = list(dd['distro'].values())
(私は同じキーの順序でkeys
、values
とitems
の戻り値をとります)。
この小さなケースでは、単純な反復アプローチがより高速であると思われます。しかし、後者のものよりはるかに大きいものがおそらくもっと良いでしょう。クロスオーバーがどこで起こるかは予測できません。
scipy.sparse
は2d行列を作成します。それはどんな種類のconst
も実装しません。 (パンダのスパースにはそのような詰め物があります)。確かにdd['size']
とdd['distro']
からsparse
の行列を作ることができました。しかし、それは速度の利点を提供するかどうかわからない。
Tensorflowが本当のターゲットである場合は、その構築方法をさらに調べる必要があります。おそらく、numpy
またはsparse
をまったく通過する必要はありません。その重要な属性である
In [247]: Xo = sparse.coo_matrix([x])
In [248]: Xo
Out[248]:
<1x10 sparse matrix of type '<class 'numpy.float64'>'
with 2 stored elements in COOrdinate format>
:const
せず
このx
は、と
scipy
スパース行列として表すことができる
In [249]: Xo.data
Out[249]: array([ 2.42, 2.56])
In [250]: Xo.row
Out[250]: array([0, 0], dtype=int32)
In [251]: Xo.col
Out[251]: array([0, 3], dtype=int32)
In [252]: Xo.shape
Out[252]: (1, 10)
Xr=Xo.tocsr()
csr
形式以外は、同様ですrow
属性はindptr
に置き換えられます配列には1行につき1つの値(+1)がありますので、非ゼロ項の数が増えるわけではありません。これは、ほとんどの疎な数学に使用されます。
実際に辞書のサブクラスであるdok
形式もあります:
In [258]: dict(Xo.todok())
Out[258]: {(0, 0): 2.4199999999999999, (0, 3): 2.5600000000000001}
入力が有効json
であれば、あなたは整数にインデックスキーを変換する必要があります。
In [281]: jstr
Out[281]: '{"distro": {"0": 2.42, "3": 2.56}, "constant": 4.55, "size": 10}'
In [282]: jdd = json.loads(jstr)
In [283]: jdd
Out[283]: {'constant': 4.55, 'distro': {'0': 2.42, '3': 2.56}, 'size': 10}
In [284]: list(jdd['distro'].keys())
Out[284]: ['0', '3']
In [285]: np.array(list(jdd['distro'].keys()),int)
Out[285]: array([0, 3])
In [286]: np.array(list(jdd['distro'].values()))
Out[286]: array([ 2.42, 2.56])
SO検索からの私の印象はjson.load
が早く、そうでない場合はeval
よりも高速であるということです。はるかに単純な構文を解析する必要があります。
python eval vs ast.literal_eval vs JSON decode
あなたがjson
文字列を処理し、そしていくつかの可能性がある何らかの中間データ構造に保存することができます。これらのベクトルはどのように「疎」ですか?辞書にほぼすべての1000の 'サイズ'のエントリの値が含まれている場合は、完全な数値配列を作成して保存することをおすすめします(例:np.save/load
ペア)。
スパースでは(値の10%が非constです)、2つのインデックスと値の配列を保存する方が意味があります(285と284)。それらを別々にしておくか、私が先に作った構造化配列のようなものに参加させてください。
はすでにかなりのスペース効率のよい(JSONを...)である(数理?)操作のどのようなあなたは、このデータ型をサポートするために必要なのですか? – Aaron
私は、その密な表現を速く作成する必要があります。 'for'ループを実行するのが遅すぎる – martianwars
この配列を作成したら、その要素にアクセスする必要があるのは何ですか?すべてのスパース配列クラスがnumpyのufuncsと他の関数をすべてサポートしているわけではありません(numpy.dotは特に注目に値するものです) – Aaron