【问题标题】:parsing json in pandas dataframe在熊猫数据框中解析 json
【发布时间】:2021-08-29 07:25:49
【问题描述】:

我需要将此响应解析为 pandas 数据框。

  "predictions": [
    {
        "predicted_label": 4.0,
        "distances": [3.11792408, 3.89746071, 6.32548437],
        "labels": [0.0, 1.0, 0.0]
    },
    {
        "predicted_label": 2.0,
        "distances": [1.08470316, 3.04917915, 5.25393973],
        "labels": [2.0, 2.0, 0.0]
    }
  ]

我正在寻找的最终结果是:

predicted_label distances labels
0 4.0 3.11792408 0.0.
1 4.0 3.89746071 1.0
2. 4.0. 6.32548437 0.0

对于第二个 predict_label 2.0 也是如此。

我尝试使用:

pd.json_normalize(result['predictions'], record_path='distances', meta='predicted_label', record_prefix='dist_')

但这不会给我标签列

【问题讨论】:

  • 非常感谢 Henry 和 Derek O!

标签: python json pandas dataframe


【解决方案1】:

我假设result 采用以下格式:

result = {"predictions": [{"predicted_label": 4.0,"distances": [3.11792408, 3.89746071, 6.32548437],"labels": [0.0, 1.0, 0.0]},{"predicted_label": 2.0,"distances": [1.08470316, 3.04917915, 5.25393973],"labels": [2.0, 2.0, 0.0]}]}

如果您将results['prediction'] 传递给pd.DataFrame,您将得到一些列表行,因为"predicted_label" 的长度为1,而"distances""labels" 的长度为3:

>>> pd.DataFrame(result['predictions'])
   predicted_label                             distances           labels
0              4.0  [3.11792408, 3.89746071, 6.32548437]  [0.0, 1.0, 0.0]
1              2.0  [1.08470316, 3.04917915, 5.25393973]  [2.0, 2.0, 0.0]

为了解决这个问题,我们可以将predicted_label 设置为索引,然后在重置索引之前将pd.Series.explode 应用于其他列(归功于@yatu 的答案here)。因为它们是列表,所以它们的类型是dobject,所以我们可以使用applymap将所有的东西都改成float类型。

将格式设置为小数点后 8 位:pd.options.display.float_format = "{:.8f}".format

>>> pd.DataFrame(result['predictions']).set_index('predicted_label').apply(pd.Series.explode).reset_index().applymap(lambda x: float(x))

   predicted_label  distances     labels
0       4.00000000 3.11792408 0.00000000
1       4.00000000 3.89746071 1.00000000
2       4.00000000 6.32548437 0.00000000
3       2.00000000 1.08470316 2.00000000
4       2.00000000 3.04917915 2.00000000
5       2.00000000 5.25393973 0.00000000

【讨论】:

  • FWIW set_index 部分是不必要的,可以很好地处理“不可爆炸”元素pd.DataFrame(result['predictions']).apply(pd.Series.explode).reset_index(drop=True)
  • 答案的一个问题是返回的数字现在是对象。他们的数字也更少。 3.11792408 与 3.117924。这会阻止我尝试完成的下一个“加入”步骤
  • 这很奇怪 - 让我看看这个,看看是否转换为字符串然后返回浮动可能是一种解决方法
  • 位数实际上并不少:可以用pd.options.display.float_format = "{:.8f}".format控制格式,例如显示小数点后的所有8位,例如
  • 我更新了答案 - 希望这会有所帮助!
【解决方案2】:

响应似乎是一堆记录 您可以一一解析,然后将它们连接在一起:

df = []
for dd in response['predictions']:
    df.append(pd.DataFrame(dd))
df = pd.concat(df).reset_index(drop=True) # reset_index if needed.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2019-01-01
    • 2014-02-01
    • 2018-04-23
    • 2013-02-09
    相关资源
    最近更新 更多