从列中的字典中提取值作为列值,NA 存在
Extract value from dict in column as column value, with NA's present
我目前正在尝试从出现在一系列专栏中的几个字典中提取值,有两个问题:
因为有 4 列有问题,所以它们是通过这行代码从以前的 dict-in-column 值中解包的:
df = pd.concat([df.drop(['ids'], axis = 1), df['ids'].apply(pd.Series)], axis = 1)
这个口述是什么 把一个口述解压到表格的列中:
d = {'a': {'id': 12}, 'b': {'id': 13}, 'c': {'id': 14}, 'd': {'id': 15}}
字典 d
的长度在 0-4 之间。
在解包数据框之前,我解包的列如下所示:
ids
406 {'a': {'id': '12'}}
408 None
409 {'a': {'id': '21'}, 'b': {'id': '23'}}
417 {'a': {'id': '53'}, 'b': {'id': '98'}, 'c': {'id': '45'}}
419 None
解压后现在的形式是
a b c
408 None {'id': '12'} None
409 {'id': '32'} {'id': '45'} {'id': '36'}
417 {'id': '09'} {'id': '31'} None
虽然最初解决了我的第一个问题,但我现在正试图从包含字典的列中提取值,对此我有点不知所措。
我尝试过的潜在解决方案只是 运行 上面每一列 (a,b,c) 的代码片段,但这既丑陋又低效。我最多知道一个简单的修复方法是在我第一次启动我的程序时 pd.json_normalize
初始数据帧,但是这需要对某些似乎可以轻松解决的问题进行重大修复和重构。作为参考,理想的输出是这样的:
a b c
408 None 12 None
409 32 45 36
417 09 31 None
整个数据框有几十万行,有 20 列在变化。
一个选项是apply
每列一个客户函数
def my_func(val):
if isinstance(val,dict):
return val['id']
else:
return val
for col in df.columns:
df[col]=df[col].apply(my_func)
a b c
0 None 12 None
1 32 45 36
2 09 31 None
- 使用来自
的解决方案
import pandas as pd
# setup dataframe
data = {'ids': [{'a': {'id': '12'}}, None, {'a': {'id': '21'}, 'b': {'id': '23'}}, {'a': {'id': '53'}, 'b': {'id': '98'}, 'c': {'id': '45'}}, None]}
df = pd.DataFrame(data)
# display(df)
ids
0 {'a': {'id': '12'}}
1 None
2 {'a': {'id': '21'}, 'b': {'id': '23'}}
3 {'a': {'id': '53'}, 'b': {'id': '98'}, 'c': {'id': '45'}}
4 None
# fill None with {}
df.ids = df.ids.fillna({i: {} for i in df.index})
# normalize the column
df = pd.json_normalize(df.ids).dropna(how='all')
# display(df)
a.id b.id c.id
0 12 NaN NaN
2 21 23 NaN
3 53 98 45
我目前正在尝试从出现在一系列专栏中的几个字典中提取值,有两个问题:
因为有 4 列有问题,所以它们是通过这行代码从以前的 dict-in-column 值中解包的:
df = pd.concat([df.drop(['ids'], axis = 1), df['ids'].apply(pd.Series)], axis = 1)
这个口述是什么 把一个口述解压到表格的列中:
d = {'a': {'id': 12}, 'b': {'id': 13}, 'c': {'id': 14}, 'd': {'id': 15}}
字典 d
的长度在 0-4 之间。
在解包数据框之前,我解包的列如下所示:
ids
406 {'a': {'id': '12'}}
408 None
409 {'a': {'id': '21'}, 'b': {'id': '23'}}
417 {'a': {'id': '53'}, 'b': {'id': '98'}, 'c': {'id': '45'}}
419 None
解压后现在的形式是
a b c
408 None {'id': '12'} None
409 {'id': '32'} {'id': '45'} {'id': '36'}
417 {'id': '09'} {'id': '31'} None
虽然最初解决了我的第一个问题,但我现在正试图从包含字典的列中提取值,对此我有点不知所措。
我尝试过的潜在解决方案只是 运行 上面每一列 (a,b,c) 的代码片段,但这既丑陋又低效。我最多知道一个简单的修复方法是在我第一次启动我的程序时 pd.json_normalize
初始数据帧,但是这需要对某些似乎可以轻松解决的问题进行重大修复和重构。作为参考,理想的输出是这样的:
a b c
408 None 12 None
409 32 45 36
417 09 31 None
整个数据框有几十万行,有 20 列在变化。
一个选项是apply
每列一个客户函数
def my_func(val):
if isinstance(val,dict):
return val['id']
else:
return val
for col in df.columns:
df[col]=df[col].apply(my_func)
a b c
0 None 12 None
1 32 45 36
2 09 31 None
- 使用来自
import pandas as pd
# setup dataframe
data = {'ids': [{'a': {'id': '12'}}, None, {'a': {'id': '21'}, 'b': {'id': '23'}}, {'a': {'id': '53'}, 'b': {'id': '98'}, 'c': {'id': '45'}}, None]}
df = pd.DataFrame(data)
# display(df)
ids
0 {'a': {'id': '12'}}
1 None
2 {'a': {'id': '21'}, 'b': {'id': '23'}}
3 {'a': {'id': '53'}, 'b': {'id': '98'}, 'c': {'id': '45'}}
4 None
# fill None with {}
df.ids = df.ids.fillna({i: {} for i in df.index})
# normalize the column
df = pd.json_normalize(df.ids).dropna(how='all')
# display(df)
a.id b.id c.id
0 12 NaN NaN
2 21 23 NaN
3 53 98 45