Python(Pandas):根据有关数据框中其他观测值的信息替换特定的 NaN 值

Python(Pandas): Replacing specific NaN values conditional on information about other observations in the dataframe

如果有一个数据框,其中每个观察都有一个标识观察的 UniqueID 和一个标识对象的 ObjectID。同一对象可以有多个观察值,即 ObjectID 不是唯一的。

一些观察结果具有变量的 Null 值,但这仅取决于对象。因此,如果一个 ObjectID 出现多次并且至少指定了一次变量,则其他观察值的 Null 值应替换为该值。

我正在使用 Python 库 Pandas (pd) 和 Numpy (np)

示例:

sample_frame = {'UniqueID': [1,2,3,4,5,6,7],"PersonID": [3,2,2,5,5,4,4], "Name": 
    ["Alice",np.nan,"Bob","Joe","Joe",np.nan,np.nan]}
sample_frame = pd.DataFrame(data = sample_frame)
sample_frame
Index UniqueID PersonID Name
0 1 3 Alice
1 2 2 Bob
2 3 2 NaN
3 4 5 Joe
4 5 5 Joe
5 6 4 NaN
6 7 4 NaN

因此,在索引为 2 的行中,Name 的 NaN 值应替换为“Bob”。 但是,下面的观察就没有办法了。

我找到了一个可行但对我来说似乎有点复杂的解决方案:

dup = sample_frame.loc[sample_frame.duplicated(subset = ["PersonID"]), :]
dup_persId = dup["PersonID"].unique()

name_na = sample_frame[sample_frame["Name"].isna()]
name_na_persId = name_na["PersonID"].unique()

dup_name_av = dup[dup["Name"].isna() == False]
dup_name_av_persId  = dup_name_av["PersonID"].unique()


for i in name_na_persId:
    
    if i in dup_name_av_persId:
        index = sample_frame.index[sample_frame["PersonID"] == i].tolist()
        
        for k in index:
            if sample_frame.at[k,"Name"] is not np.nan:
                name_temp = sample_frame.at[k,"Name"]
                continue
        
        for j in index:
            if sample_frame.at[j,"Name"] is np.nan:
                sample_frame.at[j,"Name"] = name_temp           
        
    else: 
        continue

有更简单的方法吗?

sample_frame['Name'].fillna(sample_frame.groupby('PersonID')['Name'].transform('first'))

通过 PersonID 使用 groupby,然后在 Name 列上调用 .transform('first') 将 return Name 中的第一个非 NaN 值] 该行所属的组中的列。