Python 熊猫:根据条件将空列值替换为非空值

Python 熊猫:根据条件将空列值替换为非空值,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个以下格式的数据集: 它需要按DocumentId和PersonId列分组,并按StartDate排序。我是这样做的: df=pd.read\u csv(path).sort\u值(by=[“StartDate”]).groupby([“DocumentId”,“PersonId”]) 现在,如果这个组中有一行是DocumentCodeRT且EndDate不为空的,那么所有其他行都需要在该结束日期之前填充。所以这个结果数据集应该如下: 我想不出一个办法。我想我可以迭代每个groupby

我有一个以下格式的数据集:

它需要按
DocumentId
PersonId
列分组,并按
StartDate
排序。我是这样做的:
df=pd.read\u csv(path).sort\u值(by=[“StartDate”]).groupby([“DocumentId”,“PersonId”])

现在,如果这个组中有一行是DocumentCode
RT
且EndDate不为空的,那么所有其他行都需要在该结束日期之前填充。所以这个结果数据集应该如下:

我想不出一个办法。我想我可以迭代每个groupby子集,但是如何从结束日期找到值并替换该子集中的每一行

基于使用
bfill()
的建议。我试着这样说:

df["EndDate"] = (
    df.sort_values(by=["StartDate"])
    .groupby(["DocumentId", "PersonId"])["EndDate"]
    .bfill()
)

上面的工作很好,但是如何添加DocumentCode为
RT
的条件?

您可以找到空单元格并替换为
np.nan
,然后
使用
方法

df['EndDate'] = df['EndDate'].apply(lambda x: np.nan if x=='' else x)
df['EndDate'].fillna(method = 'bfill', inplace=True)
或者,您可以从最后一行到第一行遍历df,并在必要时填写
EndDate

d = df.loc[df.shape[0]-1, 'EndDate']   #initial condition
for i in range(df.shape[0]-1, -1, -1):
    if df.loc[i, 'DocumentCode'] == 'RT':
        d = df.loc[i, 'EndDate']
    else:
        df.loc[i, 'EndDate'] = d

您可以找到空单元格并替换为
np.nan
,然后使用
method='bfill'

df['EndDate'] = df['EndDate'].apply(lambda x: np.nan if x=='' else x)
df['EndDate'].fillna(method = 'bfill', inplace=True)
或者,您可以从最后一行到第一行遍历df,并在必要时填写
EndDate

d = df.loc[df.shape[0]-1, 'EndDate']   #initial condition
for i in range(df.shape[0]-1, -1, -1):
    if df.loc[i, 'DocumentCode'] == 'RT':
        d = df.loc[i, 'EndDate']
    else:
        df.loc[i, 'EndDate'] = d

您可以计算用于在apply函数中填充nan的值

def加注结束日期(df):
rt_doc=df[df[“DocumentCode”]=“rt”]
#如果此组中有DocumentCode为RT的行
如果不是rt_doc.empty:
结束日期=rt\u doc.iloc[0][“结束日期”]
#并且EndDate不为空
如果pd.notnull(结束日期):
#所有其他行都需要在该结束日期之前填写
df=df.fillna({“结束日期”:结束日期})
返回df
df=pd.read\u csv(path).sort\u值(by=[“StartDate”])
df.groupby([“DocumentId”,“PersonId”])。应用(填写结束日期)。重置索引(drop=True)

您可以计算用于在应用函数中填充nan的值

def加注结束日期(df):
rt_doc=df[df[“DocumentCode”]=“rt”]
#如果此组中有DocumentCode为RT的行
如果不是rt_doc.empty:
结束日期=rt\u doc.iloc[0][“结束日期”]
#并且EndDate不为空
如果pd.notnull(结束日期):
#所有其他行都需要在该结束日期之前填写
df=df.fillna({“结束日期”:结束日期})
返回df
df=pd.read\u csv(path).sort\u值(by=[“StartDate”])
df.groupby([“DocumentId”,“PersonId”])。应用(填写结束日期)。重置索引(drop=True)

我想您正在寻找反向填充。您可以执行分组反向填充,这可能也与您的案例相关。谢谢@ScottBoston。我将如何使用条件检查文档代码是否为RT,然后才进行回填。我想您正在寻找反向填充。您可以执行分组反向填充,这可能也与您的案例相关。谢谢@ScottBoston。我将如何使用条件来检查DocumentCode是否为RT,然后才回填。有没有方法将
DocumentCode
条件与
fillna
一起使用?我认为
bfill
ffill
可以处理一系列问题。要依赖于其他列,您可以使用
for loop
方法,并在循环的每个步骤中定义条件,因为我被#初始条件本身卡住了。它抛出了
KeyError:4
error我的错,它应该是
df.shape[0]-1
相反,代码更新有没有办法使用
DocumentCode
条件和
fillna
?我想
bfill
ffill
处理一系列。要依赖于其他列,您可以使用
for loop
方法,并在循环的每个步骤中定义条件,因为我被#初始条件本身卡住了。它抛出了
KeyError:4
errorMy bad,它应该是
df.shape[0]-1
而不是codes UpdatedTanks@Alexander。结果数据框又添加了两个重复的列,DocumentId和PersonId,其中只有一行填充了值。@HimanshuYadav,添加了reset_index(),谢谢@Alexander。结果数据框又添加了两个重复的列,DocumentId和PersonId,其中只有一行填充了值。@HimanshuYadav,添加了reset_index()