簡體   English   中英

熊貓數據框到嵌套字典

[英]Pandas dataframe to nested dictionary

假設我的數據框看起來像這樣。

date     app_id country val1 val2 val3 val4
2016-01-01  123 US       50   70   80   90
2016-01-02  123 US       60   80   90   100
2016-01-03  123 US       70   88   99   11

我想將其轉儲到嵌套字典甚至JSON對象中,如下所示:

{
   country:
   {
       app_id: 
       {
           date: [val1, val2, val3, val4]
       }
    }
}

這樣,如果我叫my_dict['US'[123['2016-01-01']]] ,我會進入列表[50,70,80,90]

有沒有一種優雅的方法可以做到這一點? 我知道Pandas的to_dict()函數,但似乎無法繞過嵌套字典。

1創建所需的數據框。 然后使用DSM中的recur_dictify

dd=df.groupby(['country','app_id','date'],as_index=False)['val1', 'val2', 'val3', 'val4'].apply(lambda x : x.values.tolist()[0]).to_frame()

def recur_dictify(frame):
    if len(frame.columns) == 1:
        if frame.values.size == 1: return frame.values[0][0]
        return frame.values.squeeze()
    grouped = frame.groupby(frame.columns[0])
    d = {k: recur_dictify(g.iloc[:,1:]) for k,g in grouped}
    return d


recur_dictify(dd.reset_index())
Out[711]: 
{'US': {123: {'2016-01-01': [50, 70, 80, 90],
   '2016-01-02': [60, 80, 90, 100],
   '2016-01-03': [70, 88, 99, 11]}}}

更新

實際上,這可能適用於一個簡單的嵌套字典:

import pandas as pd
from collections import defaultdict

nested_dict = lambda: defaultdict(nested_dict)
output = nested_dict()

for lst in df.values:
    output[lst[1]][lst[0]][lst[2]] = lst[3:].tolist()

要么:

output = defaultdict(dict)

for lst in df.values:
    try:
        output[lst[1]][lst[0]].update({lst[2]:lst[3:].tolist()})
    except KeyError:
        output[lst[1]][lst[0]] = {}
    finally:
        output[lst[1]][lst[0]].update({lst[2]:lst[3:].tolist()})

要么:

output = defaultdict(dict)

for lst in df.values:

    if output.get(lst[1], {}).get(lst[0]) == None:
        output[lst[1]][lst[0]] = {}        
    output[lst[1]][lst[0]].update({lst[2]:lst[3:].tolist()})

output

這是我的舊解決方案,我們使用df.groupby按國家和app_id對數據df.groupby進行分組。 從這里我們收集數據(不包括國家和app_id),並使用defaultdict(dict)以嵌套的方式將數據添加到輸出字典中。

import pandas as pd
from collections import defaultdict

output = defaultdict(dict)

groups = ["country","app_id"]
cols = [i for i in df.columns if i not in groups]

for i,subdf in df.groupby(groups):
    data = subdf[cols].set_index('date').to_dict("split") #filter away unwanted cols
    d = dict(zip(data['index'],data['data'])) 
    output[i[0]][i[1]] = d # assign country=level1, app_id=level2

output

返回:

{'FR': {123: {'2016-01-01': [10, 20, 30, 40]}},
 'US': {123: {'2016-01-01': [50, 70, 80, 90],
   '2016-01-02': [60, 80, 90, 100],
   '2016-01-03': [70, 88, 99, 11]},
  124: {'2016-01-01': [10, 20, 30, 40]}}}

output['US'][123]['2016-01-01']返回:

[50, 70, 80, 90]

如果:

df = pd.DataFrame.from_dict({'app_id': {0: 123, 1: 123, 2: 123, 3: 123, 4: 124},
 'country': {0: 'US', 1: 'US', 2: 'US', 3: 'FR', 4: 'US'},
 'date': {0: '2016-01-01',
  1: '2016-01-02',
  2: '2016-01-03',
  3: '2016-01-01',
  4: '2016-01-01'},
 'val1': {0: 50, 1: 60, 2: 70, 3: 10, 4: 10},
 'val2': {0: 70, 1: 80, 2: 88, 3: 20, 4: 20},
 'val3': {0: 80, 1: 90, 2: 99, 3: 30, 4: 30},
 'val4': {0: 90, 1: 100, 2: 11, 3: 40, 4: 40}})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM