[英]Converting pandas dataframe to nested dictionary based on multi level header
我的 csv 文件有一個特定的標題,其中每個字段都包含一個用斜杠分隔的數據庫表名和列名。 簡單的例子:
user/username,user/email,user/name,address/country,address/city
我需要將 Pandas 數據框轉換為如下所示的字典:
dict = {
"user": {
"username": "",
"email": "",
"name": ""
},
"address": {
"country": "",
"city": ""
}
}
最簡單但效率不高的方法是使用 to_dict(orient='records') 方法將數據幀轉換為字典,但顯然它沒有提供所需的輸出,因此需要進行進一步處理。 在不觸及列名的情況下,我得到了一個看起來像的字典:
dict = {
"user/username": "",
"user/email":"",
"user/name":"",
"address/country":"",
"address/city":"",
}
當用分隔符分割標題時,我得到一個多級標題,但 to_dict 方法給出了一個以元組為鍵的字典,因此需要再次處理以獲得所需的輸出:
df.columns = df.columns.str.split('/', expand=True)
dict = {
("user","username"): "",
("user","email"): "",
("user","name"): "",
("address","country"): "",
("address","city"): "",
}
我還嘗試使用 itertuples() 遍歷行,但列名有問題。 當我有一個多級標題或當我用 ,,/,, 字符保留它時,它會用數字(_1、_2、_3...)替換列名。
所以無論如何,對於一個相對簡單的任務,我有一些開銷。 在讀取非常大的文件時,這種開銷可能是有問題的。
我不是常規的熊貓用戶,所以我想有一種簡單的方法可以完成這項任務,但我無法用谷歌搜索出來。
使用Index.str.split
與expand=True
創造MultiIndex
列則字典理解橫向比內level=0
列和使用DataFrame.to_dict
與orient=records
:
df.columns = df.columns.str.split('/', expand=True)
dct = {k: df[k].to_dict('r') for k in df.columns.levels[0]}
例子:
print(df)
user/username user/email user/name address/country address/city
0 A1 B1 C1 D1 E1
1 A2 B2 C2 D2 E2
print(dct)
{
'address': [
{'city': 'E1', 'country': 'D1'},
{'city': 'E2', 'country': 'D2'}
],
'user': [
{'email': 'B1', 'name': 'C1', 'username': 'A1'},
{'email': 'B2', 'name': 'C2', 'username': 'A2'}
]
}
編輯:如果需要數據框中每一行的嵌套字典,頂級鍵為user
和address
:
from collections import defaultdict
def f(df):
df = df.set_axis(
df.columns.str.split('/', expand=True), 1)
for d in df.to_dict('r'):
dct = defaultdict(dict)
for x, y in d:
dct[x][y] = d[(x, y)]
yield dict(dct)
dcts = list(f(df))
結果:
print(dcts)
[
{
'user': {'username': 'A1', 'email': 'B1', 'name': 'C1'},
'address': {'country': 'D1', 'city': 'E1'}
},
{
'user': {'username': 'A2', 'email': 'B2', 'name': 'C2'},
'address': {'country': 'D2', 'city': 'E2'}
}
]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.