-1

csv.DictReader() を使用してファイルを読み込んでいます。実際には、単一の辞書ではなく、辞書のリストを返します。単一の辞書を強制的に返すにはどうすればよいですか、または返される辞書のリストをマージするにはどうすればよいですか?

def agilent_e8361c_pna_read(file_loc):
    '''
    Load the '.s2p' file in to a dictionary.
    '''

    with open(file_loc) as f:
        # define the fields in the Agilent '.s2p' file
        col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]

        # read the data into a dictionary
        s2p_dicts = csv.DictReader(itertools.ifilter(n_input.is_comment, f), fieldnames=col_names, delimiter=' ')

    return s2p_dict

理想的には、データは最初に単一のディクショナリに読み込まれ、マージする必要はありません。一連のデータです。列は一緒に属しており、完全なセットまたは一貫したサブセットがなければ意味がありません。DictReader がこの偉業を "pythonically" 実行できない場合は、辞書のリストをマージするだけで解決します。これは、科学者もプログラマーも同様にデータセットでやりたいと思うことは珍しいことではありません。

4

3 に答える 3

4

あなたの口述が必要な場合は、次のkey:listOfValuesようにすることができます:

def transposeDict(listOfDicts):
    """Turn a list of dicts into a dict of lists.  Assumes all dicts in the list have the exact same keys."""

    keys = listOfDicts[0].iterkeys()
    return dict((key, [d[key] for d in listOfDicts]) for key in keys)

または、python2.7 以降の場合:

def transposeDict(listOfDicts):
    """Turn a list of dicts into a dict of lists.  Assumes all dicts in the list have the exact same keys."""

    keys = listOfDicts[0].iterkeys()
    return {key: [d[key] for d in listOfDicts] for key in keys}

もちろん、これはリスト内のすべての dict がまったく同じキーを持っていることを前提としています - それらは DictReader からのものです。

一般に、そうでない場合は、次のようなことをする必要があります

from collections import defaultdict

def transposeListOfDicts(listOfDicts):
    """Turn a list of dict into a dict of lists"""

    result = defaultdict(list)

    for d in listofDicts:
        for key, value in d.iteritems():
            result[key].append(item)

    return result

欠損値のプレースホルダーが必要な場合は、次のようになります。

def transposeListOfDicts(listOfDicts):
    keys = {}
    for d in listOfDicts:
        keys.update(d.iterkeys())

    return {key: [d.get(key, None) for d in listOfDicts] for key in keys}
于 2013-03-22T14:32:30.230 に答える
3

DictReadercsv.reader()レギュラーが返す各行を取得し、最初の行から渡した、または読み取ったフィールド名に基づいて辞書に変換します。これは仕様によるものです。

入力ファイルに含まれる行が1 つnext()だけの場合は、リーダーを呼び出してそれを返します。

def agilent_e8361c_pna_read(file_loc):
    with open(file_loc) as f:
        col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]

        reader = csv.DictReader(itertools.ifilter(n_input.is_comment, f), fieldnames=col_names, delimiter=' ')
        return next(reader)

next()呼び出しはブロック内にある必要があることに注意してくださいwhile。そうしないと、ファイルから読み取る前にファイルが閉じられます。

行を 1 つのディクショナリにマージする必要がある場合は、データをマージする方法を指定する必要があります。行をキーごとのリストに簡単にマージできます。

import csv

def agilent_e8361c_pna_read(file_loc):
    with open(file_loc) as f:
        col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]
        result = {k: [] for k in col_names}

        reader = csv.reader(itertools.ifilter(n_input.is_comment, f), fieldnames=col_names, delimiter=' ')
        for row in reader:
            for k, v in zip(col_names, row):
                result[k].append(v)

        return result

DictReaderここでは行ごとにディクショナリを構築していないため、その時点で はもう必要ありません。

于 2013-03-22T14:27:31.703 に答える
1

さて、これは誰かがこの問題を抱えた場合の最もエレガントな解決策です.

def agilent_e8361c_pna_read(file_loc):
    '''
    Load the '.s2p file in to a dictionary.
    '''

    with open(file_loc) as f:
        # read the data into a dictionary
        rows = csv.reader(itertools.ifilter(n_input.is_comment, f), delimiter=' ')

        # transpose data
        cols = transpose(rows)

        # create a dictionary with intuitive key names
        col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]
        s2p_dict = dict(zip(col_names,cols))

    return s2p_dict

def transpose(l):
    return map(list, zip(*l))
于 2013-03-22T15:22:11.427 に答える