Python 如何根据同一组中的其他值填充 na

How to fill na based on other value in the same group by Python

我想根据同一组中另一行的值在我的数据集中填充 NA。

数据是这样的。

 group_id, start_time, end_time  
    1, NA, 20000
    1, 40000, 20000
    1, 30000, NA
    2, NA, 35000
    2, 45000, 22000
    2, 50000,21000
    2, 45000, NA

我想得到这个结果:

 group_id, start_time, end_time  
        1, 30000, 20000
        1, 40000, 20000
        1, 30000, 20000
        2, 45000, 35000
        2, 45000, 22000
        2, 50000,21000
        2, 45000, 35000

所以每个组的第一个和最后一个值在 start_time 和 end_time 上都是相同的。

您可以创建一个循环来迭代它,如果值为 NA,则更改它

您可以使用 fillnagroupbytranformfirstlast 聚合函数来执行此操作,如 [=16= 中所述]

df['start_time'] = df['start_time'].fillna(df.groupby('group_id')['start_time'].transform('last'))
df['end_time'] = df['end_time'].fillna(df.groupby('group_id')['end_time'].transform('first'))

如果该行的条件 (is.na) 匹配,您可以使用 numpy.where 到 select 来自一列(默认值)的值,否则 select 来自其他列的值(在本例中为同一列)。

import pandas as pd
import numpy as np
from io import StringIO

TESTDATA = """
group_id,start_time,end_time
1,NA,20000
1,40000,20000
1,30000,NA
2,NA,35000
2,45000,22000
2,50000,21000
2,45000,NA
"""
df = pd.read_csv(StringIO(TESTDATA), sep=",") # parse your sample data

在这种情况下,您要求的默认值是每个组的 first/last,因此我们需要为这些构造列:

start_time_last = df.groupby("group_id")["start_time"].last()
end_time_first = df.groupby("group_id")["end_time"].first()
merged = df.join(start_time_last, on='group_id', how='left', rsuffix='_last').join(end_time_first, on='group_id', how='left', rsuffix='_first')

现在我们可以使用 np.where 来填写 na 值:

merged["start_time"] = np.where(pd.isna(merged["start_time"]), merged["start_time_last"], merged["start_time"])
merged["end_time"] = np.where(pd.isna(merged["end_time"]), merged["end_time_first"], merged["end_time"])
print(merged)

给出:

   group_id  start_time  end_time  start_time_last  end_time_first
0         1     30000.0   20000.0          30000.0         20000.0
1         1     40000.0   20000.0          30000.0         20000.0
2         1     30000.0   20000.0          30000.0         20000.0
3         2     45000.0   35000.0          45000.0         35000.0
4         2     45000.0   22000.0          45000.0         35000.0
5         2     50000.0   21000.0          45000.0         35000.0
6         2     45000.0   35000.0          45000.0         35000.0