首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python pandas,如何以最有效的方式将pandas列与json解压到新的数据帧中?

问Python pandas,如何以最有效的方式将pandas列与json解压到新的数据帧中?
EN

Stack Overflow用户
提问于 2020-01-16 22:22:43
回答 2查看 86关注 0票数 0

我有一个清单:

代码语言:javascript
复制
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系列中,我想创建一个新的数据帧。我试着这样做:

​

​

一切正常,但我不希望每个单元格都在列表中。我试过了:

​

​

...which可以工作,但由于有十亿分之一的数据行数,它的速度非常慢。有没有一种矢量化的方法可以在没有单元格列表的data_list中创建字段数据帧?

EN

回答 2

Stack Overflow用户

发布于 2020-01-16 22:37:06

您可以使用:

代码语言:javascript
复制
df = pd.DataFrame(data_list)
out = pd.DataFrame(df['fields'].tolist()).stack().str[0].unstack()

代码语言:javascript
复制
  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推断正确的数据类型

代码语言:javascript
复制
out1 = (pd.DataFrame(df['fields'].tolist()).stack().str[0]
                  .astype(object).unstack().infer_objects())

我们也可以直接做pd.io.json.json_normalize:

代码语言:javascript
复制
df = pd.io.json.json_normalize(data_list).rename(columns=lambda x: x.split('.')[1])
df.stack().str[0].astype(object).unstack().infer_objects()

代码语言:javascript
复制
print(out.dtypes)
#standard       object
#serviceCode    object
#deltaUpload    object
#dtype: object

print(out1.dtypes)
#standard       object
#serviceCode    object
#deltaUpload     int64
dtype: object
票数 1
EN

Stack Overflow用户

发布于 2020-01-17 13:18:42

pandas中的json_normalize函数并不是特别快。我建议您将初始数据缩减为列表或字典,然后创建数据帧:

代码语言:javascript
复制
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 /循环(平均值±标准dev.共7次运行,每次1000次循环)。

随着时间的推移,我们学到了更多:更短的代码,更干净的代码:

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59771692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档