按行线性插补

Row-wise linear imputation

我有一个具有时间序列特征的数据框。我想用逐行线性插补来插补缺失值。

作为一个可重现的例子:

import pandas as pd
import numpy as np
df = pd.DataFrame({'id': range(2), 
                   'F1_Date_1': [1,2], 
                   'F1_Date_2': [np.nan,4], 
                   'F1_Date_3': [3, 6],
                   'F1_Date_4': [4,8], 
                   'F2_Date_1': [2,11], 
                   'F2_Date_2': [6, np.nan], 
                   'F2_Date_3': [10, np.nan],
                   'F2_Date_4': [14, 17]})
df

   id  F1_Date_1  F1_Date_2  ...  F2_Date_2  F2_Date_3  F2_Date_4
0   0          1        NaN  ...        6.0       10.0         14
1   1          2        4.0  ...        NaN        NaN         17

对于 F1,我想使用 F1_Date_1F1_Date_3 线性估算(插值)F1_Date_2。对于 F2,我想使用 F2_Date_1F2_Date_4

来估算 F2_Date_2F2_Date_3

期望的输出是

final_df = pd.DataFrame({'id': range(2), 
                   'F1_Date_1': [1,2], 
                   'F1_Date_2': [2,4], 
                   'F1_Date_3': [3, 6],
                   'F1_Date_4': [4,8], 
                   'F2_Date_1': [2,11], 
                   'F2_Date_2': [6, 13], 
                   'F2_Date_3': [10, 15],
                   'F2_Date_4': [14, 17]})

   id  F1_Date_1  F1_Date_2  ...  F2_Date_2  F2_Date_3  F2_Date_4
0   0          1          2  ...          6         10         14
1   1          2          4  ...         13         15         17

如何在 Python 中高效地处理非常大的数据集(可能有 1000 万行、8 个日期和 15 个特征)?

我设法通过熔化、插值和 'unmelting' 数据帧来做到这一点。

df = pd.melt(df, id_vars=["id"])
df = df.groupby(df['variable'].str[:2]).apply(lambda g: g.interpolate()).pivot_table(index='id', columns='variable', values='value').reset_index().rename_axis(None, axis=1)
df

每列使用 groupby - _ 之前的值,如 F1, F2 和自定义插值函数:

df = (df.set_index('id')
        .groupby(lambda x: x.split('_')[0], axis=1)
        .apply(lambda x: x.interpolate(axis=1)))

print (df)
    F1_Date_1  F1_Date_2  F1_Date_3  F1_Date_4  F2_Date_1  F2_Date_2  \
id                                                                     
0         1.0        2.0        3.0        4.0        2.0        6.0   
1         2.0        4.0        6.0        8.0       11.0       13.0   

    F2_Date_3  F2_Date_4  
id                        
0        10.0       14.0  
1        15.0       17.0  

IIUC,你想做row-wise插值:

final_df = df.interpolate(axis=1)

如果每个部分的最外面的列,即F1_Date_1F1_Date_4F2_Date_1和[=14,则无需明确区分F1和F2部分=] 不包含任何缺失值。