首页 > 解决方案 > Pandas:将包含 JSON 编码观察数组的列展开为行

问题描述

将包含 JSON 编码观察数组的列扩展为其他行的惯用 Pandas 方法是什么?

在下面的示例中Out[3]DataFrame包含贷款数据。每笔贷款有一行。Loan IDStart DateEnd Date和列Amount在贷款期限内不变。Payments零个或多个带日期戳的付款作为 JSON(字符串)数组编码到列中。

Jupyter 截图

中的目标输出Out[5]显示了目标。每个原始行一个或多个行,每次付款都会Payments导致在输出中创建一个新行。

我已经完成了这两种方法:使用iterrows,它看起来清晰且易于阅读,以及使用一种复杂的、有点手摇的方法,我将固定属性拉入索引以保留它们,然后melt重新索引。

一定会有更好的办法!请分享熊猫大师的秘密:)

标签: pandas

解决方案


首先删除NaNcolumn Paymentsby中的 s 并将 sdropna转换jsondicts by ast.literal_eval

import ast

s = df['Payments'].dropna().apply(ast.literal_eval)
print (s)
0    [{'Payment Amount': 1000, 'Payment Date': '201...
Name: Payments, dtype: object

然后将每个值转换为DataFrameinlist comprehensionconcattogether -keys参数对于对齐原始行很重要:

df1 = pd.concat([pd.DataFrame(x) for x in s], keys=s.index)
print (df1)
     Payment Amount Payment Date
0 0            1000   2018-03-11
  1            2000   2018-03-13
  2            3000   2018-03-15

删除列和join原始DataFrame,最后为唯一索引添加reset_index

df = df.drop('Payments', 1).join(df1.reset_index(level=1, drop=True)).reset_index(drop=True)
df['Payment Date'] = pd.to_datetime(df['Payment Date'])
print (df)
   LoanId  Start Date    End Date  Amount  Payment Amount Payment Date
0     100  2018-01-01  2021-01-01   10000          1000.0   2018-03-11
1     100  2018-01-01  2021-01-01   10000          2000.0   2018-03-13
2     100  2018-01-01  2021-01-01   10000          3000.0   2018-03-15
3     101  2018-01-02  2021-01-02   20000             NaN          NaT
4     102  2018-01-03  2021-01-03   30000             NaN          NaT

推荐阅读