将包含JSON编码观察数组的列扩展为其他行的惯用Pandas方法是什么?
在下面的示例中,Out[3]
是包含贷款数据的DataFrame
。每笔贷款有一排。 Loan ID
,Start Date
,End Date
和Amount
列不会在贷款期限内发生变化。零个或多个带日期戳的付款将作为JSON(字符串)数组编入Payments
列。
Out[5]
中的目标输出显示了目标。每个原始行一行或多行,每次付款Payments
,导致在输出中创建新行。
我已经完成了这两种方式:使用iterrows
,它看起来很容易阅读,并且使用了一种复杂的,有点手绘的方法,我将固定属性拉入索引以保留它们,然后melt
并重新编制索引。
一定有更好的方法!请分享一下熊猫大师的秘密:)
答案 0 :(得分:3)
首先在dropna
栏中删除NaN
栏中的Payments
,然后ast.literal_eval
将json
转换为dict
:
import ast
s = df['Payments'].dropna().apply(ast.literal_eval)
print (s)
0 [{'Payment Amount': 1000, 'Payment Date': '201...
Name: Payments, dtype: object
然后将DataFrame
和concat
中的每个值转换为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