将包含 JSON 编码的观察数组的列扩展为其他行的惯用 Pandas 方法是什么?
在下面的示例中Out[3]是一个DataFrame包含贷款数据。每笔贷款有一行。列Loan ID、Start Date、End Date和Amount不会在贷款期限内发生变化。零个或多个带日期戳的付款Payments作为 JSON(字符串)数组编码到列中。
中的目标输出Out[5]显示了目标。每个原始行一行或多行,每次付款都会Payments导致在输出中创建一个新行。
我已经完成了这两种方法: with iterrows,它看起来很正常且易于阅读,以及使用一种复杂的、有点笨拙的方法,我将固定属性拉入索引以保留它们,然后melt重新索引。
一定会有更好的办法!请分享熊猫大师的秘密:)
首先删除NaNS IN列Payments通过dropna并转换jsons到dict由s 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
Run Code Online (Sandbox Code Playgroud)
然后将每个值转换为DataFrameinlist comprehension并concat一起转换-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
Run Code Online (Sandbox Code Playgroud)
删除列并添加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
Run Code Online (Sandbox Code Playgroud)