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,则更改它
您可以使用 fillna
、groupby
、tranform
和 first
或 last
聚合函数来执行此操作,如 [=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
我想根据同一组中另一行的值在我的数据集中填充 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,则更改它
您可以使用 fillna
、groupby
、tranform
和 first
或 last
聚合函数来执行此操作,如 [=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