【问题标题】:Converting Pandas DataFrame to JSON将 Pandas DataFrame 转换为 JSON
【发布时间】:2021-03-29 03:02:03
【问题描述】:

我将数据存储在 pandas 数据框中,我想将 tat 转换为 JSON 格式。可以使用以下代码复制示例数据

data = {'Product':['A', 'B', 'A'],
        'Zone':['E/A', 'A/N', 'E/A'],
        'start':['08:00:00', '09:00:00', '12:00:00'],
        'end':['12:30:00', '17:00:00', '17:40:00'],
        'seq':['0, 1, 2 ,3 ,4','0, 1, 2 ,3 ,4', '0, 1, 2 ,3 ,4'],
        'store':['Z',"'AS', 'S'", 'Z']
        }

df = pd.DataFrame(data)

我尝试使用以下代码将其转换为 JSON 格式

df_parsed = json.loads(df.to_json(orient="records"))

从上面生成的输出

[{'Product': 'A', 'Zone': 'E/A', 'start': '08:00:00', 'end': '17:40:00', 'seq': '0, 1, 2 ,3 ,4', 'store': 'Z'}, {'Product': 'B', 'Zone': 'A/N', 'start': '09:00:00', 'end': '17:00:00', 'seq': '0, 1, 2 ,3 ,4', 'store': 'AS'}, {'Product': 'A', 'Zone': 'E/A', 'start': '08:00:00', 'end': '17:40:00', 'seq': '0, 1, 2 ,3 ,4', 'store': 'Z'}]

期望的结果:

{
'A': {'Zone': 'E/A', 
'tp': [{'start': [8, 0], 'end': [12, 0], 'seq': [0, 1, 2 ,3 ,4]},
      {'start': [12, 30], 'end': [17, 40], 'seq': [0, 1, 2 ,3 ,4]}],
      
'store': ['Z']
}, 
'B': {'Zone': 'A/N', 
'tp': [{'start': [9, 0], 'end': [17, 0], 'seq': [0, 1, 2 ,3 ,4]}],
      
'store': ['AS', 'S']
}
}

如果产品属于同一商店,则应将列 start、end 和 seq 的结果合并,如所需输出所示。如果时间的值为"09:00:00",则开始时间和结束时间也应表示为[9,0],只需要表示小时和分钟,因此我们可以从time 列中丢弃秒值。

【问题讨论】:

  • 在转换为 JSON 格式之前,您需要先转换 DataFrame。例如,您可以尝试使用 df.groupby('Product') 或其他 pandas 方法聚合数据。
  • @Sura-da 如果答案对数据框进行了一些操作,那么它就可以了。和groupby 应该用于俱乐部数据
  • 如果我的回答有帮助,请点击勾选将其标记为已接受的答案。

标签: python json pandas dataframe to-json


【解决方案1】:

这会有点复杂。所以你必须一步一步来:

def funct(row):
    row['start'] = row['start'].str.split(':').str[0:2]
    row['end'] = row['end'].str.split(':').str[0:2]
    row['store'] = row['store'].str.replace("'", "").str.split(', ')

    d = (row.groupby('Zone')[row.columns[1:]]
        .apply(lambda x: x.to_dict(orient='record'))
        .reset_index(name='tp').to_dict(orient='row'))
    return d

di = df.groupby(['Product'])[df.columns[1:]].apply(funct).to_dict()

di:

{'A': [{'Zone': 'E/A',
   'tp': [{'start': ['08', '00'],
     'end': ['12', '30'],
     'seq': '0, 1, 2 ,3 ,4',
     'store': ['Z']},
    {'start': ['12', '00'],
     'end': ['17', '40'],
     'seq': '0, 1, 2 ,3 ,4',
     'store': ['Z']}]}],
 'B': [{'Zone': 'A/N',
   'tp': [{'start': ['09', '00'],
     'end': ['17', '00'],
     'seq': '0, 1, 2 ,3 ,4',
     'store': ['AS', 'S']}]}]}

解释:

  • 首先创建您自己的自定义函数。
  • 将start、end 列更改为列表形式。
  • 按Zone 分组并将to_dict 应用于其余列。
  • 重置索引并命名具有[{'start': ['08', '00'], 'end': ['12', '30'], 'seq': '0, 1, 2 ,3 ,4',的列 作为tp。
  • 现在将 to_dict 应用于整个结果并返回它。

一旦你能够做到这一点,你最终需要将你的数据框转换成下面的格式,剩下的事情对你来说就变得容易了。

Zone    tp
E/A    [{'start': ['08', '00'], 'end': ['12', '30'], ...
A/N    [{'start': ['09', '00'], 'end': ['17', '00'], ... 

编辑:

import pandas as pd
import ast

def funct(row):
    y = row['start'].str.split(':').str[0:-1]
    row['start'] = row['start'].str.split(':').str[0:2].apply(lambda x: list(map(int, x)))
    row['end'] = row['end'].str.split(':').str[0:2].apply(lambda x: list(map(int, x)))
    row['seq'] = row['seq'].apply(lambda x: list(map(int, ast.literal_eval(x))))
    row['store'] = row['store'].str.replace("'", "")

    d = (row.groupby('Zone')[row.columns[1:-1]]
        .apply(lambda x: x.to_dict(orient='record'))
        .reset_index(name='tp'))
    ######### For store create a different dataframe and then merge it to the other df ########
    d1 = (row.groupby('Zone').agg({'store': pd.Series.unique}))
    d1['store'] = d1['store'].str.split(",")
    d_merged = (pd.merge(d,d1, on='Zone', how='left')).to_dict(orient='record')[0]
    return d_merged

di = df.groupby(['Product'])[df.columns[1:]].apply(funct).to_dict()

di:

{'A': {'Zone': 'E/A',
  'tp': [{'start': [8, 0], 'end': [12, 30], 'seq': [0, 1, 2, 3, 4]},
   {'start': [12, 0], 'end': [17, 40], 'seq': [0, 1, 2, 3, 4]}],
  'store': ['Z']},
 'B': {'Zone': 'A/N',
  'tp': [{'start': [9, 0], 'end': [17, 0], 'seq': [0, 1, 2, 3, 4]}],
  'store': ['AS', ' S']}}
 

【讨论】:

  • 您的答案几乎是正确的,除了一些属于期望结果的一部分但无法通过您的解决方案实现的事情。例如 start 、end 和 seq 形式不是字符串,您可以参考我的问题以查看所需的实际输出。开始/结束应表示为[8, 0],序列也应表示为[1, 2, 3, 4, 5]。您已经将store 与tp 联系在一起,您可以看到我想要的结果,它不是tp 的一部分您能提供修复吗?
猜你喜欢
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 2019-06-09
  • 2017-01-08
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多