【问题标题】:How to convert dataframe to a json string and apply some transformations to this string?如何将数据框转换为 json 字符串并对这个字符串应用一些转换?
【发布时间】:2017-06-15 12:04:01
【问题描述】:

我想将我的数据框转换为 json 字符串。如果我只是做df.to_json(orient='records'),那么它转换得很好。但是,我想在 json 字符串中进行一些转换。

这是我的数据框df

df = 
GROUP   HOUR    AVG_MINUTES   AVG_GRADE
AAA     7       67            5.5
AAA     8       58            6.5
AAA     9       55            4.5
BBB     7       15            5.1
BBB     8       18            5.4
CCC     9       34            5.5

json 字符串应如下所示:

[
{
"GROUP":"AAA",
"AVG_MINUTES":[[7,67],[8,58],[9,55]],
"AVG_GRADE":[[7,5.5],[8,6.5],[9,4.5]]
},
{
"GROUP":"BBB",
"AVG_MINUTES":[[7,15],[8,18],[9,34]],
"AVG_GRADE":[[7,5.1],[8,5.4],[9,5.5]]
}
]

我想在AVG_MINUTESAVG_GRADE 的每一对中获取HOUR 值。有可能吗?还是我应该手动完成? (这将是一个坏消息,因为数据框很大)

【问题讨论】:

    标签: python json pandas


    【解决方案1】:

    您可以先在AVG_MINUTESAVG_GRADE 列中创建lists。然后groupbyaggregate tolist() 最后使用DataFrame.to_dict 和参数orient='records'

    df.AVG_MINUTES = df[['HOUR','AVG_MINUTES']].values.tolist()
    df.AVG_GRADE = df[['HOUR','AVG_GRADE']].values.tolist()
    
    print (df)
      GROUP  HOUR AVG_MINUTES   AVG_GRADE
    0   AAA     7     [7, 67]  [7.0, 5.5]
    1   AAA     8     [8, 58]  [8.0, 6.5]
    2   AAA     9     [9, 55]  [9.0, 4.5]
    3   BBB     7     [7, 15]  [7.0, 5.1]
    4   BBB     8     [8, 18]  [8.0, 5.4]
    5   CCC     9     [9, 34]  [9.0, 5.5]
    
    df = df.groupby('GROUP')['AVG_MINUTES','AVG_GRADE']
           .agg(lambda x : x.tolist())
           .reset_index()
           .to_dict(orient='records')
    print (df)
    [
    {'GROUP': 'AAA', 
     'AVG_GRADE': [[7.0, 5.5], [8.0, 6.5], [9.0, 4.5]], 
     'AVG_MINUTES': [[7, 67], [8, 58], [9, 55]]}, 
    {'GROUP': 'BBB', 
     'AVG_GRADE': [[7.0, 5.1], [8.0, 5.4]],
     'AVG_MINUTES': [[7, 15], [8, 18]]}, 
    {'GROUP': 'CCC',
     'AVG_GRADE': [[9.0, 5.5]],
     'AVG_MINUTES': [[9, 34]]}
    ]
    

    如果使用DataFrame.to_json 输出类似 - 输出中的HOUR 是由zip 创建的int,其中输出是list of tuplesmap 转换为list of lists 的内容:

    df.AVG_MINUTES = list(map(list, zip(df.HOUR, df.AVG_MINUTES)))
    df.AVG_GRADE = list(map(list, zip(df.HOUR, df.AVG_GRADE)))
    
    print (df)
      GROUP  HOUR AVG_MINUTES AVG_GRADE
    0   AAA     7     [7, 67]  [7, 5.5]
    1   AAA     8     [8, 58]  [8, 6.5]
    2   AAA     9     [9, 55]  [9, 4.5]
    3   BBB     7     [7, 15]  [7, 5.1]
    4   BBB     8     [8, 18]  [8, 5.4]
    5   CCC     9     [9, 34]  [9, 5.5]
    
    df = df.groupby('GROUP')['AVG_MINUTES','AVG_GRADE']
           .agg(lambda x : x.tolist())
           .reset_index()
           .to_json(orient='records')
    print (df)
    [{"GROUP":"AAA",
    "AVG_MINUTES":[[7,67],[8,58],[9,55]],
    "AVG_GRADE":[[7,5.5],[8,6.5],[9,4.5]]},
    {"GROUP":"BBB",
    "AVG_MINUTES":[[7,15],[8,18]],
    "AVG_GRADE":[[7,5.1],[8,5.4]]},
    {"GROUP":"CCC",
    "AVG_MINUTES":[[9,34]],
    "AVG_GRADE":[[9,5.5]]}]
    

    【讨论】:

    • 嗯,我测试了你的第一个解决方案,我得到了[{'AVG_MINUTES': [67,58,55] 而不是'AVG_MINUTES':[[7,67],[8,58],[9,55]]AVG_GRADE 也是如此。
    • 你先用df.AVG_MINUTES = df[['HOUR','AVG_MINUTES']].values.tolist() df.AVG_GRADE = df[['HOUR','AVG_GRADE']].values.tolist()吗?
    • 我在转换为lists 后添加到df 的答案输出
    • 太棒了,这并不容易。很高兴能帮到你。
    • 嗯,我认为第一个解决方案的问题是values 转换为numpy array,如果第二列中有一些floats,则所有值都转换为float。因此,如果需要 hoursint,则需要使用另一种解决方案。
    猜你喜欢
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2013-10-26
    • 1970-01-01
    • 2022-01-13
    • 2019-12-17
    • 2020-05-08
    相关资源
    最近更新 更多