Python 熊猫:基于日期的缺失值插补

Python 熊猫:基于日期的缺失值插补,python,pandas,dataframe,imputation,Python,Pandas,Dataframe,Imputation,我有一个熊猫数据框,如下所示: df_first = pd.DataFrame({"id": [102, 102, 102, 102, 103, 103], "val1": [np.nan, 4, np.nan, np.nan, 1, np.nan], "val2": [5, np.nan, np.nan, np.nan, np.nan, 5], "rand": [np.nan, 3, 7, 8, np.nan, 4], "val3": [5, np.nan, np.nan, np.nan, 3

我有一个熊猫数据框,如下所示:

df_first = pd.DataFrame({"id": [102, 102, 102, 102, 103, 103], "val1": [np.nan, 4, np.nan, np.nan, 1, np.nan], "val2": [5, np.nan, np.nan, np.nan, np.nan, 5], "rand": [np.nan, 3, 7, 8, np.nan, 4], "val3": [5, np.nan, np.nan, np.nan, 3, np.nan], "unique_date": [pd.Timestamp(2002, 3, 3), pd.Timestamp(2002, 3, 5), pd.Timestamp(2003, 4, 5), pd.Timestamp(2003, 4, 9), pd.Timestamp(2003, 8, 7), pd.Timestamp(2003, 9, 7)], "end_date": [pd.Timestamp(2005, 3, 3), pd.Timestamp(2003, 4, 7), np.nan, np.nan, pd.Timestamp(2003, 10, 7), np.nan]})
df_first

    id  val1  val2  rand  val3 unique_date   end_date
0  102   NaN   5.0   NaN   5.0  2002-03-03 2005-03-03
1  102   4.0   NaN   3.0   NaN  2002-03-05 2003-04-07
2  102   NaN   NaN   7.0   NaN  2003-04-05        NaT
3  102   NaN   NaN   8.0   NaN  2003-04-09        NaT
4  103   1.0   NaN   NaN   3.0  2003-08-07 2003-10-07
5  103   NaN   5.0   4.0   NaN  2003-09-07        NaT
缺失值插补应以如下方式进行:从具有
end\u date
值的数据框中向前填充每行中出现的值

只要相同的
id
唯一日期早于
结束日期
,则执行正向填充

根据上面最后一段所述,应按照
id
进行正向填充

最后,缺失值插补应仅针对某些名称中包含
val
的列进行。一个重要的注意事项是,没有其他列的名称中有这种模式。如果我没有说得足够清楚,上面发布的数据帧的解决方案如下所示:

    id  val1  val2  rand  val3 unique_date
0  102   NaN   5.0   NaN   5.0  2002-03-03
1  102   4.0   5.0   3.0   5.0  2002-03-05
2  102   4.0   5.0   7.0   5.0  2003-04-05
3  102   NaN   5.0   8.0   5.0  2003-04-09
4  103   1.0   NaN   NaN   3.0  2003-08-07
5  103   1.0   5.0   4.0   3.0  2003-08-07
如果你需要进一步澄清,请告诉我,因为乍一看整个事情似乎相当复杂


期待你的回答

对不起,这个问题和解释都很混乱。最后,我能够通过以下方式实现我想要的

df_first = pd.DataFrame({"id": [102, 102, 102, 102, 103, 103],
                         "val1": [np.nan, 4, np.nan, np.nan, 1, np.nan],
                         "val2": [5, np.nan, np.nan, np.nan, np.nan, 5],
                         "val3": [np.nan, 3, np.nan, np.nan, np.nan, 4],
                         "val4": [5, np.nan, np.nan, np.nan, 3, np.nan],
                         "rand": [3, np.nan, 1, np.nan, 5, 6],
                         "unique_date": [pd.Timestamp(2002, 3, 3),
                                         pd.Timestamp(2002, 3, 5),
                                         pd.Timestamp(2003, 4, 5),
                                         pd.Timestamp(2003, 4, 9),
                                         pd.Timestamp(2003, 8, 7),
                                         pd.Timestamp(2003, 9, 7)],
                        "end_date": [pd.Timestamp(2005, 3, 3),
                                     pd.Timestamp(2003, 4, 7),
                                     np.nan,
                                     np.nan,
                                     pd.Timestamp(2003, 10, 7),
                                     np.nan]})
display(df_first)

indexes = []
columns = df_first.filter(like="val").columns
for column in columns:
    indexes.append(df_first.columns.get_loc(column))

elements = df_first.values[:,indexes]
ids = df_first.values[:,df_first.columns.get_loc("id")]
start_dates = df_first.values[:,df_first.columns.get_loc("unique_date")]
end_dates = df_first.values[:,df_first.columns.get_loc("end_date")]

for i in range(len(elements)):
    if pd.notnull(end_dates[i]):
        not_nan_indexes = np.argwhere(~pd.isnull(elements[i])).ravel()
        elements_prop = elements[i,not_nan_indexes]
        j = i
        while (j < len(elements) and start_dates[j] < end_dates[i] and ids[i] == ids[j]):
            elements[j, not_nan_indexes] =  elements_prop
            j+=1

df_first[columns] = elements
df_first = df_first.drop(columns="end_date")
display(df_first)
df_first=pd.DataFrame({“id”:[102102102102103103],
“val1:[np.nan,4,np.nan,np.nan,1,np.nan],
“val2:[5,np.nan,np.nan,np.nan,np.nan,5],
“val3”:[np.nan,3,np.nan,np.nan,np.nan,4],
“val4:[5,np.nan,np.nan,np.nan,3,np.nan],
“兰德”:[3,np.nan,1,np.nan,5,6],
“唯一日期”:[pd.时间戳(2002,3,3),
pd.时间戳(2002,3,5),
pd.时间戳(2003,4,5),
pd.时间戳(2003,4,9),
pd.时间戳(2003,8,7),
pd.时间戳(2003年9月7日)],
“结束日期”:[pd.时间戳(2005,3,3),
pd.时间戳(2003,4,7),
np.nan,
np.nan,
pd.时间戳(2003,10,7),
np.nan]})
显示(df_优先)
索引=[]
columns=df_first.filter(like=“val”).columns
对于列中的列:
index.append(df_first.columns.get_loc(column))
元素=df_first.值[:,索引]
ids=df_first.values[:,df_first.columns.get_loc(“id”)]
开始日期=df_first.values[:,df_first.columns.get_loc(“唯一日期”)]
结束日期=df_first.values[:,df_first.columns.get_loc(“结束日期”)]
对于范围内的i(len(元素)):
如果pd.notnull(结束日期[i]):
not_nan_index=np.argwhere(~pd.isnull(elements[i])).ravel()
elements\u prop=元素[i,而非索引]
j=i
而(j

可能解决方案有些过火,但我找不到任何具体的方法来实现我想要的。

您已经尝试了什么?您能告诉我这个示例数据的“val3”是如何向前填充的吗?@coldspeed与其他“val”列相同。这样看,“id”的人在“唯一日期”开始服用“val”药物,一直服用到“结束日期”。“唯一_日期”还与该人员“id”的其他事件相关联。其他事件是本例中的其他列“rand”。这就是为什么有几行具有相同的“id”和不同的“unique_date”(与此人相关的其他事件发生在其他日期)。@sundance如果我从数据以及要编辑的列的索引中提取numpy矩阵,我知道如何执行此操作。然后,进行正向插补,并将数据转换回数据帧。