我有多索引数据,需要在每个 ID 的第一个和最后一个可用值之间填充 NaN

问题描述 投票:0回答:1

我有一个如下所示的示例数据集。请注意,

['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)
python pandas pivot interpolation
1个回答
0
投票

使用

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'])
© www.soinside.com 2019 - 2024. All rights reserved.