183

「データ」と「マッピング」の 2 つの CSV ファイルがあります。

  • 「マッピング」ファイルには、、、、、の 4 つの列Device_NameGDNありDevice_TypeますDevice_OS。4 つの列すべてが入力されます。
  • 「データ」ファイルにはこれらと同じ列があり、列にデータDevice_Nameが入力され、他の 3 つの列は空白になっています。
  • Python コードで両方のファイルを開きDevice_Name、データ ファイルのそれぞれに対して、そのGDNDevice_Type、およびDevice_OS値をマッピング ファイルからマッピングする必要があります。

2 列しか存在しない場合 (1 列をマップする必要がある場合) dict を使用する方法は知っていますが、3 列をマップする必要がある場合にこれを達成する方法がわかりません。

以下は、のマッピングを達成しようとしたコードですDevice_Type

x = dict([])
with open("Pricing Mapping_2013-04-22.csv", "rb") as in_file1:
    file_map = csv.reader(in_file1, delimiter=',')
    for row in file_map:
       typemap = [row[0],row[2]]
       x.append(typemap)

with open("Pricing_Updated_Cleaned.csv", "rb") as in_file2, open("Data Scraper_GDN.csv", "wb") as out_file:
    writer = csv.writer(out_file, delimiter=',')
    for row in csv.reader(in_file2, delimiter=','):
         try:
              row[27] = x[row[11]]
         except KeyError:
              row[27] = ""
         writer.writerow(row)

返しますAttribute Error

いくつかの調査の後、ネストされた辞書を作成する必要があると思いますが、これを行う方法がわかりません。

4

9 に答える 9

376

ネストされた dict は、辞書内の辞書です。非常に単純なことです。

>>> d = {}
>>> d['dict1'] = {}
>>> d['dict1']['innerkey'] = 'value'
>>> d['dict1']['innerkey2'] = 'value2'
>>> d
{'dict1': {'innerkey': 'value', 'innerkey2': 'value2'}}

パッケージの を使用して、ネストされた辞書の作成を容易にすることもできdefaultdictますcollections

>>> import collections
>>> d = collections.defaultdict(dict)
>>> d['dict1']['innerkey'] = 'value'
>>> d  # currently a defaultdict type
defaultdict(<type 'dict'>, {'dict1': {'innerkey': 'value'}})
>>> dict(d)  # but is exactly like a normal dictionary.
{'dict1': {'innerkey': 'value'}}

必要に応じて入力できます。

次のようなコードをお勧めします。

d = {}  # can use defaultdict(dict) instead

for row in file_map:
    # derive row key from something 
    # when using defaultdict, we can skip the next step creating a dictionary on row_key
    d[row_key] = {} 
    for idx, col in enumerate(row):
        d[row_key][idx] = col

あなたのコメントによると:

上記のコードが質問を混乱させている可能性があります。簡単に言えば、私の問題: a.csv b.csv という 2 つのファイルがあり、a.csv には ijkl という 4 つの列があり、b.csv にもこれらの列があります。i は、これらの csv のキー列の一種です。jkl 列は a.csv では空ですが、b.csv では入力されています。「i」をキー列として使用して jk l 列の値を b.csv から a.csv ファイルにマップしたい

私の提案は次のようなものです(defaultdictを使用せずに):

a_file = "path/to/a.csv"
b_file = "path/to/b.csv"

# read from file a.csv
with open(a_file) as f:
    # skip headers
    f.next()
    # get first colum as keys
    keys = (line.split(',')[0] for line in f) 

# create empty dictionary:
d = {}

# read from file b.csv
with open(b_file) as f:
    # gather headers except first key header
    headers = f.next().split(',')[1:]
    # iterate lines
    for line in f:
        # gather the colums
        cols = line.strip().split(',')
        # check to make sure this key should be mapped.
        if cols[0] not in keys:
            continue
        # add key to dict
        d[cols[0]] = dict(
            # inner keys are the header names, values are columns
            (headers[idx], v) for idx, v in enumerate(cols[1:]))

ただし、csv ファイルを解析するためにcsv モジュールがあることに注意してください。

于 2013-05-02T08:24:17.403 に答える
71

更新: ネストされた辞書の任意の長さについては、この回答に移動してください。

コレクションの defaultdict 関数を使用します。

ハイパフォーマンス: データセットが大きい場合、「if key not in dict」は非常に高価です。

低メンテナンス: コードを読みやすくし、簡単に拡張できるようにします。

from collections import defaultdict

target_dict = defaultdict(dict)
target_dict[key1][key2] = val
于 2015-12-07T20:22:38.063 に答える
2
pip install addict
from addict import Dict

mapping = Dict()
mapping.a.b.c.d.e = 2
print(mapping)  # {'a': {'b': {'c': {'d': {'e': 2}}}}}

参考文献:

  1. easydict GitHub
  2. 常習者 GitHub
于 2021-04-20T10:06:01.817 に答える
0
#in jupyter
import sys
!conda install -c conda-forge --yes --prefix {sys.prefix} nested_dict 
import nested_dict as nd
d = nd.nested_dict()

'd' を使用して、ネストされたキーと値のペアを格納できるようになりました。

于 2021-03-10T14:44:35.323 に答える