3

私はPythonを初めて使用し、Matlabからジャンプすることにしました。私は自分の質問に対する答えを何日も見つけようとしましたが、成功しませんでした!

問題: 特定の属性を持つオブジェクトがたくさんあります。プログラミングの意味でのオブジェクトと属性について話しているのではないことに注意してください。さまざまな種類の数値データと物理的属性がある文字通りの天体オブジェクトについて話しているのです。

スクリプトのループでは、カタログ内の各ソース/オブジェクトを調べ、いくつかの計算を行い、結果を巨大な辞書に貼り付けます。スクリプトの形式は次のようになります。

for i in range ( len(ObjectCatalogue) )

    calculate quantity1 for source i    

    calculate quantity2 for source i 

    determine attribute1 for source i 

    sourceDataDict[i].update( {'spectrum':quantity1} )

    sourceDataDict[i].update( {'peakflux':quantity2} )

    sourceDataDict[i].update( {'morphology':attribute1} )

つまり、100 ほどのソースを調べたら、オブジェクト番号のスペクトルにアクセスできます。20 で、spectrumSource20 = sourceData[20]['spectrum'] など。

私がやりたいことは、「形態学」というキーワードの値に基づいて、辞書内のすべてのオブジェクトを選択できるようにすることです。たとえば、'morphology' のキーワードは、'simple' または 'complex' の値を取ることができます。とにかく、ループに頼らずにこれを行うことができますか? つまり、'morphology' キーワードの 'complex' 値を取るすべてのソースを含む新しい辞書を作成するようなことはできますか?

説明するのは難しいですが、Matlab で慣れ親しんだ論理インデックスを使用すると、次のようになります。

complexSourceDataDict = sourceDataDict[*]['morphology'=='complex']

(* はディクショナリ内のすべてのオブジェクトを示します)

とにかく - どんな助けでも大歓迎です!

4

4 に答える 4

3

ループがなければ、いいえ。リスト内包表記を使用すると、はい:

complex = [src for src in sourceDataDict.itervalues() if src.get('morphology') == 'complex']

sourceDataDict本当にリストである場合は、次のものを削除できますitervalues

complex = [src for src in sourceDataDict if src.get('morphology') == 'complex']

考えてみると、 a を評価する*と、内部でループ操作が行われることを意味します (有効な構文であると仮定して)。したがって、あなたの秘訣は、使用しているデータ構造でできる限り効率的なループを行うことです。

より効率的にする唯一の方法は、すべてのデータ オブジェクトの「形態」キーに事前にインデックスを付け、それらを最新の状態に保つことです。

于 2012-11-19T06:51:49.873 に答える
1

ネストされた辞書を順不同でインデックス付けする直接的な方法はありません。これは、目的の構文で行う必要があるためです。ただし、Python でそれを行う方法はいくつかあり、さまざまなインターフェイスとパフォーマンス特性があります。

最良の解決策は、関心のある特性によってインデックスを作成する追加の辞書を作成することです。たとえば、'morphology'値が である値を見つけるには'complex'、次のようにします。

from collections import defaultdict

# set up morphology dict (you could do this as part of generating the morphology)
morph_dict = defaultdict(list)
for data in sourceDataDict.values():
    morph_dict[data["morphology"]].append(data)

# later, you can access a list of the values with any particular morphology
complex_morph = morph_dict["complex"]

これは高性能ですが、事前にすべての逆索引を設定しなければならないのは煩わしいかもしれません。別の方法として、リスト内包表記またはジェネレーター式を使用して辞書を反復処理し、適切な値を見つけることもできます。

complex = (d for d in sourceDataDict.values() if d["morphology"] == "complex")

for c in complex:
    do_whatever(c)
于 2012-11-19T06:58:18.243 に答える
1

次のような構造を扱っていると思います

sourceDataDict = [
    {'spectrum':1,
    'peakflux':10,
     'morphology':'simple'
    },
    {'spectrum':2,
    'peakflux':11,
     'morphology':'comlex'
     },
    {'spectrum':3,
    'peakflux':12,
     'morphology':'simple'
     },
    {'spectrum':4,
    'peakflux':13,
     'morphology':'complex'
     }
    ]

List COmprehension を使用して同様のことができます

>>> [e for e in sourceDataDict if e.get('morphology',None) == 'complex']
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

itertools.ifilter を使用すると、同様の結果を得ることができます

>>> list(itertools.ifilter(lambda e:e.get('morphology',None) == 'complex', sourceDataDict))
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

インデックス作成の代わりに get を使用するのは、キー「形態」が存在しない場合でも機能が失敗しないようにするためです。存在することが確実な場合は、上記を次のように書き換えることができます

>>> [e for e in sourceDataDict if e['morphology'] == 'complex']
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

>>> list(itertools.ifilter(lambda e:e['morphology'] == 'complex', sourceDataDict))
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]
于 2012-11-19T06:54:50.843 に答える
0

大量のデータを処理する場合は、データをどこかに保存することをお勧めします。たとえば、ある種のデータベースとORM(たとえば)ですが、後者は好みの問題です。ある種のRDBMSが解決策かもしれません。

生のPythonに関しては、 filterのような機能ルーチンを除いて組み込みのソリューションはありません。とにかく、あるステップで反復に直面します(暗黙的かどうかは関係ありません)。

最も簡単な方法は、属性値としてキーを使用して追加のdictを保持することです。

objectsBy['morphology'] = {'complex': set(), 'simple': set()}

for item in sources:
  ...
  objMorphology = compute_morphology(item)
  objectsBy['morphology'][objMorphology] += item
  ...
于 2012-11-19T07:01:49.680 に答える