0

ndarray大きなnumpy (最大16次元の〜1milエントリのセット)を、配列の2つの次元によって2つのサブグループに編成しようとしています。

現在、itertool のgroupby関数を使用していますが、それが辞書に作成する値はitertools._grouperオブジェクトであり、何をしてもオブジェクトndarrayに変換されるようです。grouper

この問題を解決するためにカスタム関数を作成することはできますが、これを防ぐ方法やオブジェクトをwith に戻すgroupby方法がわからないことは、私が非常に慣れていない言語である Python でのコーディング能力の根本的な問題のようです。正しいフィールド。後で操作するためにフィールドを維持する必要があるため、 が必要です。grouperndarrayndarray

次のコードを修正して、返さgroupbyれた結果を完全に元に戻すndarrayか、変換を防止するにはどうすればよいですか?

array = np.sort(array, order=['Front','Back','SecStruc'])
front_dict = dict((k,v) for k,v in groupby(array, lambda array : array['Front']))
for key in front_dict:
    front_dict[key] = dict((k,list(v)) for k,v in groupby(front_dict[key], 
    lambda array : front_dict[key]['Back']))

ありがとう!

4

2 に答える 2

2

これでお使いいただけるかと思いますnumpy.split。次のようにして、配列をサブ配列に分割できます。

import numpy as np

def findsplit(a):
    diff = a[1:] != a[:-1]
    edges = np.where(diff)[0]
    return edges + 1

array = np.array([0,0,0,1,1,1,1,2,2,3,4,4,4])
s = np.split(array, findsplit(array))
for a in s:
    print a
# [0 0 0]
# [1 1 1 1]
# [2 2]
# [3]
# [4 4 4]

質問で記述したネストされた辞書を取得するには、次のようにします。

byFront = np.split(array, findsplit(array['Front']))
front_dict = {}
for sameFront in byFront:
    back_dict = {}
    byBack = np.split(sameFront, findsplit(sameFront['Back']))
    for sameBack in byBack:
        back_dict[sameBack['Back'][0]] = sameBack
    front_dict[sameFront['Front'][0]] = back_dict
于 2013-11-05T07:51:03.997 に答える
0

あなたはほとんどそこにいるようです。 list(v)簡単に配列に変換できるリストです。

x=np.array([0,0,0,1,1,1,1,2,2,3,4,4,4])
{k:np.array(list(v)) for k,v in groupby(x)}

{0: array([0, 0, 0]),
 1: array([1, 1, 1, 1]),
 2: array([2, 2]),
 3: array([3]),
 4: array([4, 4, 4])}

または、2 次元配列 (最初の列でグループ化し、次に最後の列でグループ化) を使用します。

x=np.array([[0,1,2],[1,2,3],[1,2,4],[1,0,4],[2,3,1]])
d={k:list(v) for k,v in groupby(x,lambda s:s[0])}
print d
# {0: [array([0, 1, 2])],
#  1: [array([1, 2, 3]), array([1, 2, 4]), array([1, 0, 4])],
#  2: [array([2, 3, 1])]}
for i in d.keys():
    d[i]={k:np.array(list(v)) for k,v in groupby(list(d[i]),lambda s:s[2])}
print d
# {0: {2: array([[0, 1, 2]])},
#  1: {3: array([[1, 2, 3]]), 4: array([[1, 2, 4], [1, 0, 4])},
#  2: {1: array([[2, 3, 1]])}}
print d[1][4]
#  [[1 2 4]
#   [1 0 4]]

どちらの段階でlist(v)or -を使用するかは大した問題ではありません(1 番目の次元での反復に関心がある場合)。np.array(list(v))


numpy documentation から適応した構造化配列を使用する

x = np.array([(1.5,2.5,(1.0,2.0)),(1.5,2.5,(2.0,4.0)),(3.,4.,(4.,5.)),(1.,3.,(2.,6.))],
        dtype=[('x','f4'),('y',np.float32),('value','f4',(2,2))])
d={k:list(v) for k,v in groupby(x,lambda s:s['x'])}
for i in d.keys():
    d[i]={k:list(v) for k,v in groupby(list(d[i]),lambda s:s['y'])}
pprint(d)
for dd in d[1.5][2.5]:
    print dd
print d[1.5][2.5][0].dtype
# [('x', '<f4'), ('y', '<f4'), ('value', '<f4', (2, 2))]
dd = np.array(d[1.5][2.5],dtype=x.dtype)
print dd
print dd.dtype
print dd[0]
# (1.5, 2.5, [[1.0, 2.0], [1.0, 2.0]])
print dd['value']
# [[[ 1.  2.] [ 1.  2.]]
#  [[ 2.  4.] [ 2.  4.]]]

「最も内側」の要素の構造化配列文字は保持されます。np.array(...,dtype=x.dtype)これらの配列のリストを 1 つの配列に変換したい場合にのみ使用する必要があります(例: dd)。

d[1.5][2.5][0]['value']1.52.5はディクショナリ キー、0はリスト インデックス、valueは構造体配列フィールド名です。


しかし、この使用法はgroupby本当に必要なのでしょうか? 通常のnumpyインデックスで最後の「値」を取得できます。そして、「行」はxソートする必要はありません。非常に大きな配列では、速度とメモリの使用が重要な考慮事項になる可能性があります。

I=(x['x']==1.5)&(x['y']==2.5)
print x[I]['value']
于 2013-11-05T06:16:25.710 に答える