[英]What is the most efficient way to "flatten" a JSON within a dataframe in pandas?
[英]Python pandas, how to unpack pandas column with json to new dataframe in most efficient way?
我有一個清單:
data_list= [
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [0]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [545618]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [597561]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [323771]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [1088]
}
}
]
從這個列表中,我創建了一個數據框:
從 df.fields 系列我想創建一個新的數據框。 我試過:
一切正常,但我不希望每個單元格都在列表中。 我試過:
...這有效但由於數百萬數據行而非常慢。 是否有矢量化方法可以從沒有單元格列表的 data_list 中創建字段數據框?
您可以使用:
df = pd.DataFrame(data_list)
out = pd.DataFrame(df['fields'].tolist()).stack().str[0].unstack()
standard serviceCode deltaUpload
0 ADSL1 BNG_DSL 0
1 ADSL1 BNG_DSL 545618
2 ADSL1 BNG_DSL 597561
3 ADSL1 BNG_DSL 323771
4 ADSL1 BNG_DSL 1088
我們也可以嘗試使用infer_objects
推斷正確的infer_objects
out1 = (pd.DataFrame(df['fields'].tolist()).stack().str[0]
.astype(object).unstack().infer_objects())
我們也可以直接做pd.io.json.json_normalize
:
df = pd.io.json.json_normalize(data_list).rename(columns=lambda x: x.split('.')[1])
df.stack().str[0].astype(object).unstack().infer_objects()
print(out.dtypes)
#standard object
#serviceCode object
#deltaUpload object
#dtype: object
print(out1.dtypes)
#standard object
#serviceCode object
#deltaUpload int64
dtype: object
pandas 中的 json_normalize 函數並不是特別快。 我建議您將初始數據減少到列表或字典,然后創建您的數據框:
d = [(i['fields']['standard'][0],
i['fields']['serviceCode'][0],
i['fields']['deltaUpload'][0])
if i['fields']['standard'] else ''
if i['fields']['serviceCode'] else ''
if i['fields']['deltaUpload'] else ''
for i in data_list ]
d
[('ADSL1', 'BNG_DSL', 0),
('ADSL1', 'BNG_DSL', 1088),
('ADSL1', 'BNG_DSL', 323771),
('ADSL1', 'BNG_DSL', 545618),
('ADSL1', 'BNG_DSL', 597561)]
df = pd.DataFrame(d)
df.columns = ['standard','serviceCode','deltaUpload']
standard serviceCode deltaUpload
0 ADSL1 BNG_DSL 545618
1 ADSL1 BNG_DSL 1088
2 ADSL1 BNG_DSL 323771
3 ADSL1 BNG_DSL 597561
4 ADSL1 BNG_DSL 0
在我的 PC 上運行的時間:每個循環 596 µs ± 14.7 µs(平均值 ± 標准偏差,7 次運行,每次 1000 次循環)。
時間過去了,我們學到了更多:更短的代碼,更清晰:
from collections import defaultdict
d = defaultdict(list)
for entry in data_list:
for k,v in entry['fields'].items():
d[k].append(v[0])
pd.DataFrame(d)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.