首页 > 解决方案 > 根据其他 DataFrame 填充日期内的值

问题描述

我正在尝试填充这个 DataFrame (df1)(我可以用 NaN 或零值开始它):

        27/05/2021  28/05/2021  29/05/2021  30/05/2021  31/05/2021  01/06/2021  02/06/2021 ...
Name1   Nan         Nan         Nan         Nan         Nan         Nan         Nan
Name2   Nan         Nan         Nan         Nan         Nan         Nan         Nan
Name3   Nan         Nan         Nan         Nan         Nan         Nan         Nan
Name4   Nan         Nan         Nan         Nan         Nan         Nan         Nan

在此 DataFrame (df2) 中记录信息:

          Start1      End1        Dedication1 (h) Start2      End2        Dedication2 (h) 
Name1     24/05/2021  31/05/2021  8               02/06/2021  10/07/2021  3
Name2     29/05/2021  31/05/2021  5               Nan         Nan         Nan
Name3     27/05/2021  01/06/2021  3               Nan         Nan         Nan
Name4     29/05/2021  07/08/2021  8               10/10/2021  10/12/2021  2

要得到这样的东西(df3):

        27/05/2021  28/05/2021  29/05/2021  30/05/2021  31/05/2021  01/06/2021  02/06/2021 ...
Name1   8           8           8           8           8           0           3
Name2   0           0           5           5           5           0           0
Name3   3           3           3           3           3           3           0
Name4   0           0           8           8           8           8           8

这是一个连续几个月每天工作时间的时间表。两个 DataFrame 将具有相同的索引和行号。

根据 df2 中的日期,我需要在开始日和结束日填写 df1 值,并在此期间提供奉献时间。

我尝试了包括所有行的 loc 和 lambda 函数来根据日期选择列,但我没有在日期内获得填充值。也许我需要几个步骤。

谢谢。

标签: pythonpandaslambda

解决方案


你可以试试这个:

from datetime import datetime
import pandas as pd

# Setup
limits = [("Start1", "End1", "Dedication1"), ("Start2", "End2", "Dedication2")]
df3 = df1.copy()

# Deal with NaN values
df3.fillna(0, inplace=True)
df2["Start2"].fillna("31/12/2099", inplace=True)
df2["End2"].fillna("31/12/2099", inplace=True)
df2["Dedication2"].fillna(0, inplace=True)

# Iterate and fill df3
for i, row in df1.iterrows():
    for col in df1.columns:
        for start, end, dedication in limits:
            mask = (
                datetime.strptime(df2.loc[i, start], "%d/%m/%Y")
                <= datetime.strptime(col, "%d/%m/%Y")
                <= datetime.strptime(df2.loc[i, end], "%d/%m/%Y")
            )
            if mask:
                df3.loc[i, col] = df2.loc[i, dedication]

# Format df3
df3 = df3.astype("int")

print(df3)
# Outputs
       27/05/2021  28/05/2021  29/05/2021  ...  31/05/2021  01/06/2021  02/06/2021
Name1           8           8           8  ...           8           0           3
Name2           0           0           5  ...           5           0           0
Name3           3           3           3  ...           3           3           0
Name4           0           0           8  ...           8           8           8

推荐阅读