[英]Pandas dataframe to list of dicts
我有 Dataframe ,如下所示。 它包含有關計划、活動和項目的信息。 每個計划包含多個活動,每個活動包含多個項目。
| plan_id | plan_name | activity_id | activity_name | item_id | item_name |
| --------| --------- |------------ |-------------- |-------- |---------- |
| 1 | plan1 | 1 | activity1 | 1 | item1 |
| 1 | plan1 | 2 | activity2 | 3 | item3 |
| 2 | plan2 | 1 | activity1 | 1 | item1 |
我想將其轉換為字典列表
[
{
'plan_id':1,
'plan_name':plan1,
activities:
[
{
activity_id: 1,
activity_name: 'activity1'
items:
[
{
'item_id:1,
'item_name':'item1'
}
]
},
{
activity_id: 2,
activity_name: 'activity2'
items:
[
{
'item_id:3,
'item_name':'item3'
}
]
}
]
},
{
'plan_id':2,
'plan_name':plan2,
activities:
[
{
activity_id: 1,
activity_name: 'activity1'
items:
[
{
'item_id:1,
'item_name':'item1'
}
]
}
]
}
]
有什么快速的方法可以做到這一點嗎?
更新
我發現一種解決方案是創建 3 個數據框 - 包含項目、活動和計划,並像這樣循環它們:
plans_dict = plans_df.to_dict('records')
for plan in plans_dict:
plan['activities'] = activities_df[activities_df['id']==plan['id']].to_dict('records')
for activity in plan['activities']:
activity['items'] = items_df[items_df['activity_id']==activity['activity_id']].to_dict('records')
我不確定這是否是最快的解決方案。 還有其他想法嗎?
這個怎么樣:
def group_dict(df, name, keys):
gkeys = [k for k in df.columns if k not in keys]
r = df.groupby(gkeys)[keys].apply(pd.DataFrame.to_dict, orient='records')
return r.to_frame(name).reset_index()
def to_grouped_dicts(df):
df1 = group_dict(df, 'items', ['item_id', 'item_name'])
df2 = group_dict(df1, 'activities', ['activity_id', 'activity_name', 'items'])
return df2.to_dict(orient='records')
然后:
>>> to_grouped_dicts(df)
[{'plan_id': 1,
'plan_name': 'plan1',
'activities': [{'activity_id': 1,
'activity_name': 'activity1',
'items': [{'item_id': 1, 'item_name': 'item1'}]},
{'activity_id': 2,
'activity_name': 'activity2',
'items': [{'item_id': 3, 'item_name': 'item3'}]}]},
{'plan_id': 2,
'plan_name': 'plan2',
'activities': [{'activity_id': 1,
'activity_name': 'activity1',
'items': [{'item_id': 1, 'item_name': 'item1'}]}]}]
這個想法是收集給定組的字典列表。 例如,第一行:
df1 = group_dict(df, 'items', ['item_id', 'item_name'])
做一個df.groupby('plan_id', 'plan_name', 'activity_id', 'activity_name')
; 對於每個這樣的組,它會查看所需的鍵( ['item_id', 'item_name']
)並將包含該內容的字典列表放入一個名為'items'
的新列中:
print(df1)
plan_id plan_name activity_id activity_name \
0 1 plan1 1 activity1
1 1 plan1 2 activity2
2 2 plan2 1 activity1
items
0 [{'item_id': 1, 'item_name': 'item1'}]
1 [{'item_id': 3, 'item_name': 'item3'}]
2 [{'item_id': 1, 'item_name': 'item1'}]
然后我們對“下一級”應用相同的邏輯(制作一列'activities'
)。
對於測試,這是一種構建任意大小的df
的方法,如示例:
n = 100_000
df = pd.DataFrame({
'plan_id': np.random.randint(0, 20, size=n),
'activity_id': np.random.randint(0, 20, size=n),
'item_id': np.random.randint(0, 20, size=n),
})
df = df.assign(**{
k.replace('_id', '_name'): k.replace('_id', '_') + v
for k, v in df.astype(str).items()
})
在這樣一個 100K df
上,時間是:
%timeit to_grouped_dicts(df)
# 314 ms ± 940 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
在這種情況下,它實際上比單個簡單的.to_dict()
快一點:
%timeit df.to_dict(orient='records')
# 509 ms ± 579 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
速度比取決於各個組的重復程度。 .to_dict()
不做任何分組,所以它必須吐出每一行的每一個單元格。 如果發生的分組較少,則to_grouped_dicts()
可能比.to_dict()
慢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.