3

ここでPythonは初めてです。私は何時間も髪を引っ張っていますが、それでもこれを理解することはできません。

辞書のリストがあります:

[ {'FX0XST001.MID5': '195', 'Name': 'Firmicutes', 'Taxonomy ID': '1239', 'Type': 'phylum'}
  {'FX0XST001.MID13': '4929', 'Name': 'Firmicutes', 'Taxonomy ID': '1239','Type': 'phylum'},
  {'FX0XST001.MID6': '826', 'Name': 'Firmicutes', 'Taxonomy ID': '1239', 'Type': 'phylum'},
                                        .
                                        .
                                        .
                                        .

  {'FX0XST001.MID6': '125', 'Name': 'Acidobacteria', 'Taxonomy ID': '57723', 'Type': 'phylum'}
  {'FX0XST001.MID25': '70', 'Name': 'Acidobacteria', 'Taxonomy ID': '57723', 'Type': 'phylum'}
  {'FX0XST001.MID40': '40', 'Name': 'Acidobacteria', 'Taxonomy ID': '57723', 'Type': 'phylum'} ]

タイプ、名前、分類IDに基づいてリスト内の辞書をマージしたい

  [ {'FX0XST001.MID5': '195', 'FX0XST001.MID13': '4929', 'FX0XST001.MID6': '826', 'Name': 'Firmicutes', 'Taxonomy ID': '1239', 'Type': 'phylum'}
                                        .
                                        .
                                        .
                                        .

    {'FX0XST001.MID6': '125', 'FX0XST001.MID25': '70', 'FX0XST001.MID40': '40', 'Name': 'Acidobacteria', 'Taxonomy ID': '57723', 'Type': 'phylum'}]

後でcsv.DictWriterを使用してCSVにデータを書き込む必要があるため、このようなデータ構造を設定しています。

誰かが親切に私を正しい方向に向けてくれませんか?

4

4 に答える 4

5

これには、groupby関数を使用できます。

http://docs.python.org/library/itertools.html#itertools.groupby

from itertools import groupby

keyfunc = lambda row : (row['Type'], row['Taxonomy ID'], row['Name'])

result = []

data = sorted(data, key=keyfunc)
for k, g in groupby(data, keyfunc):
    # you can either add the matching rows to the item so you end up with what you wanted
    item = {}        
    for row in g:
        item.update(row)
    result.append(item)

    # or you could just add the matched rows as subitems to a parent dictionary
    # which might come in handy if you need to work with just the parts that are
    # different
    item = {'Type': k[0], 'Taxonomy ID' : k[1], 'Name' : k[2], 'matches': [])
    for row in g:
        del row['Type']
        del row['Taxonomy ID']
        del row['Name']
        item['matches'].append(row)
    result.append(item)  
于 2012-10-05T21:18:53.450 に答える
3

いくつかのテストデータを作成します。

list_of_dicts = [
                 {"Taxonomy ID":1, "Name":"Bob", "Type":"M", "hair":"brown", "eyes":"green"},
                 {"Taxonomy ID":1, "Name":"Bob", "Type":"M", "height":"6'2''", "weight":200},
                 {"Taxonomy ID":2, "Name":"Alice", "Type":"F", "hair":"black", "eyes":"hazel"},
                 {"Taxonomy ID":2, "Name":"Alice", "Type":"F", "height":"5'7''", "weight":145}
                ]    

これ(以下)は、他のソリューションreduceを改善するための巧妙なトリックだと思います。groupby

import itertools
def key_func(elem):
    return (elem["Taxonomy ID"], elem["Name"], elem["Type"])

output_list_of_dicts = [reduce((lambda x,y: x.update(y) or x), list(val)) for key, val in itertools.groupby(list_of_dicts, key_func)]

次に、出力を出力します。

for elem in output_list_of_dicts:
    print elem

これは印刷します:

{'eyes': 'green', 'Name': 'Bob', 'weight': 200, 'Taxonomy ID': 1, 'hair': 'brown', 'height': "6'2''", 'Type': 'M'}
{'eyes': 'hazel', 'Name': 'Alice', 'weight': 145, 'Taxonomy ID': 2, 'hair': 'black', 'height': "5'7''", 'Type': 'F'}

参考までに、Python Pandasは、この種の集計には、特に.csvまたは.h5ファイルへのファイルI / Oを処理する場合に、他のものよりもはるかにitertools優れています。

于 2012-10-05T21:31:05.477 に答える
2

おそらく最も簡単な方法は、(Type、Name、Taxonomy ID)タプルでインデックス付けされた新しい辞書を作成し、(Type、Name、Taxonomy ID)で値を格納して、辞書を反復処理することです。これを簡単にするには、デフォルトのdictを使用します。例えば:

from collections import defaultdict
grouped = defaultdict(lambda : {})

# iterate over items and store:
for entry in list_of_dictionaries:
    grouped[(entry["Type"], entry["Name"], entry["Taxonomy ID"])].update(entry)

# now you have everything stored the way you want in values, and you don't
# need the dict anymore
grouped_entries = grouped.values()

これは少しハックです。特に、使用するたびに「Type」、「Name」、「Phylum」を上書きしてしまうためですupdateが、dictキーは可変であるため、これが最善の方法かもしれません。これにより、少なくとも必要なものに近づくことができます。

さらに良いのは、最初のインポートでこれを行い、中間のステップをスキップすることです(実際に事前にデータを変換する必要がある場合を除く)。さらに、変化するフィールドのみを取得できる場合は、を次のように変更できますupdategrouped[(type, name, taxonomy_id)][key] = valueここで、キーと値は次のようになります:'FX0XST001.MID5'、 '195'

于 2012-10-05T21:23:32.400 に答える
0
from itertools import groupby

data = [ {'FX0XST001.MID5': '195', 'Name': 'Firmicutes', 'Taxonomy ID': '1239', 'Type':'phylum'},
  {'FX0XST001.MID13': '4929', 'Name': 'Firmicutes', 'Taxonomy ID': '1239','Type': 'phylum'},
  {'FX0XST001.MID6': '826', 'Name': 'Firmicutes', 'Taxonomy ID': '1239', 'Type': 'phylum'},
  {'FX0XST001.MID6': '125', 'Name': 'Acidobacteria', 'Taxonomy ID': '57723', 'Type': 'phylum'},
  {'FX0XST001.MID25': '70', 'Name': 'Acidobacteria', 'Taxonomy ID': '57723', 'Type': 'phylum'},
  {'FX0XST001.MID40': '40', 'Name': 'Acidobacteria', 'Taxonomy ID': '57723', 'Type': 'phylum'} ,]

kk = ('Name', 'Taxonomy ID', 'Type')

def key(item): return tuple(item[k] for k in kk)

result = []
data = sorted(data, key=key)
for k, g in groupby(data, key):
    result.append(dict((i, j) for d in g for i,j in d.items()))


print result
于 2012-10-05T22:15:07.503 に答える