我有一个如下所示的示例数据集。请注意,
['ID', 'Date']
构成索引。
身份证 | 日期 | 价值A | 价值B | 价值C |
---|---|---|---|---|
A | 2020年1月1日 | NaN | NaN | NaN |
A | 2020年1月2日 | 1 | 5 | 7 |
A | 2020年1月3日 | NaN | 6 | 8 |
A | 2020年1月4日 | 2 | NaN | NaN |
A | 2020年1月5日 | 2 | NaN | 7 |
B | 2020年1月1日 | 2 | NaN | 6 |
B | 2020年1月2日 | 3 | 5 | 7 |
B | 2020年1月3日 | NaN | NaN | NaN |
B | 2020年1月4日 | 5 | NaN | 10 |
B | 2020年1月5日 | 5 | 8 | NaN |
以下是所需的输出
身份证 | 日期 | 价值A | 价值B | 价值C |
---|---|---|---|---|
A | 2020年1月1日 | NaN | NaN | NaN |
A | 2020年1月2日 | 1 | 5 | 7 |
A | 2020年1月3日 | 1 | 6 | 8 |
A | 2020年1月4日 | 2 | NaN | 8 |
A | 2020年1月5日 | 2 | NaN | 7 |
B | 2020年1月1日 | 2 | NaN | 6 |
B | 2020年1月2日 | 3 | 5 | 7 |
B | 2020年1月3日 | 3 | 5 | 7 |
B | 2020年1月4日 | 5 | 5 | 10 |
B | 2020年1月5日 | 5 | 8 | NaN |
对于每个ID,我需要在ValueA/ValueB/ValueC中填充NaN值,但区域仅限于内部。我试过了:
df_padded = df.interpolate(limit_area='inside')
df_fill = df.fillna(method="ffill")
mask = df_padded.isna()
df_fill[mask] = np.nan
上面的代码在处理单个 ID 时有效。但由于数据集中存在多个 ID,输出变为:
身份证 | 日期 | 价值A | 价值B | 价值C |
---|---|---|---|---|
A | 2020年1月1日 | NaN | NaN | NaN |
A | 2020年1月2日 | 1 | 5 | 7 |
A | 2020年1月3日 | 1 | 6 | 8 |
A | 2020年1月4日 | 2 | 6 | 8 |
A | 2020年1月5日 | 2 | 6 | 7 |
B | 2020年1月1日 | 2 | 6 | 6 |
B | 2020年1月2日 | 3 | 5 | 7 |
B | 2020年1月3日 | 3 | 5 | 7 |
B | 2020年1月4日 | 5 | 5 | 10 |
B | 2020年1月5日 | 5 | 8 | NaN |
我也尝试过应用以下功能,但无法将其设置为多索引以查看是否可以应用蒙版。
def fwdfill(df_monthlies):
ID_list = df_monthlies['ID'].unique().tolist()
for ID in ID_LIST:
ID_data = df_monthlies[df_monthlies['ID'] == ID]
ID_data = ID_data.sort_values(by=['Date'])
ID_data = ID_data.reset_index(drop=True)
使用
df.groupby
。
选项 1 (
apply
)
out = (
df.reset_index()
.groupby('ID', group_keys=False)
.apply(lambda x: x.interpolate('pad', limit_area='inside', axis=1))
.set_index(['ID', 'Date'])
)
选项 2 (
transform
)
out2 = df.reset_index()
cols =['ValueA', 'ValueB', 'ValueC']
out2[cols] = (
out2.groupby('ID')[cols]
.transform(lambda x: x.interpolate('pad', limit_area='inside'))
)
out2 = out2.set_index(['ID', 'Date'])
out2.equals(out)
# True
输出:
ValueA ValueB ValueC
ID Date
A 01-01-2020 NaN NaN NaN
01-02-2020 1.0 5.0 7.0
01-03-2020 1.0 6.0 8.0
01-04-2020 2.0 NaN 8.0
01-05-2020 2.0 NaN 7.0
B 01-01-2020 2.0 NaN 6.0
01-02-2020 3.0 5.0 7.0
01-03-2020 3.0 5.0 7.0
01-04-2020 5.0 5.0 10.0
01-05-2020 5.0 8.0 NaN
使用的数据
import pandas as pd
import numpy as np
data = {'ID': {0: 'A', 1: 'A', 2: 'A', 3: 'A', 4: 'A', 5: 'B', 6: 'B',
7: 'B', 8: 'B', 9: 'B'},
'Date': {0: '01-01-2020', 1: '01-02-2020', 2: '01-03-2020', 3: '01-04-2020',
4: '01-05-2020', 5: '01-01-2020', 6: '01-02-2020', 7: '01-03-2020',
8: '01-04-2020', 9: '01-05-2020'},
'ValueA': {0: np.nan, 1: 1.0, 2: np.nan, 3: 2.0, 4: 2.0, 5: 2.0, 6: 3.0,
7: np.nan, 8: 5.0, 9: 5.0},
'ValueB': {0: np.nan, 1: 5.0, 2: 6.0, 3: np.nan, 4: np.nan, 5: np.nan,
6: 5.0, 7: np.nan, 8: np.nan, 9: 8.0},
'ValueC': {0: np.nan, 1: 7.0, 2: 8.0, 3: np.nan, 4: 7.0, 5: 6.0, 6: 7.0,
7: np.nan, 8: 10.0, 9: np.nan}}
df = pd.DataFrame(data).set_index(['ID', 'Date'])