Pandas:将包含JSON编码的观察数组的列展开为行

时间:2018-04-27 02:08:05

标签: pandas

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

在下面的示例中,Out[3]是包含贷款数据的DataFrame。每笔贷款有一排。 Loan IDStart DateEnd DateAmount列不会在贷款期限内发生变化。零个或多个带日期戳的付款将作为JSON(字符串)数组编入Payments列。

Jupyter screenshot

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

我已经完成了这两种方式:使用iterrows,它看起来很容易阅读,并且使用了一种复杂的,有点手绘的方法,我将固定属性拉入索引以保留它们,然后melt并重新编制索引。

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

1 个答案:

答案 0 :(得分:3)

首先在dropna栏中删除NaN栏中的Payments,然后ast.literal_evaljson转换为dict

import ast

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

然后将DataFrameconcat中的每个值转换为list comprehension - 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