处理 Pandas 中 ID 组的有效方法

san*_*oxj 2 python pandas

df = pd.DataFrame({
    'caseid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
    'timestamp': [10, 20, 30, 10, 20, 30, 10, 20, 30] 
    'var1': [np.nan, np.nan, np.nan, 10, np.nan, 11, 12, 13, 14],
    'var2': [2., 3., 4., np.nan, 5., 6., np.nan, np.nan, np.nan]
    })
Run Code Online (Sandbox Code Playgroud)

我需要找到每个变量的第一个(和最后一个)有效时间戳caseid。即对于var1caseid1 它将是None,对于caseid2 它将是10(最后一个30)。对于每个附加的 var 列也是如此。

是否有处理 id 组而无需循环caseid并在每列上执行 a first_valid_index(),因为使用 pandas 时循环不是最有效的?

moz*_*way 6

您可以使用(或手动)选择所需的列filter,然后用时间戳替换非 NA 值(使用mulwhere),最后使用groupby.aggfirst/ last

m = df.filter(like='var').notna()

out = (m.mul(df['timestamp'], axis=0).where(m)
        .groupby(df['caseid']).agg(['first', 'last'])
      )
Run Code Online (Sandbox Code Playgroud)

输出:

        var1        var2      
       first  last first  last
caseid                        
1        NaN   NaN  10.0  30.0
2       10.0  30.0  20.0  30.0
3       10.0  30.0   NaN   NaN
Run Code Online (Sandbox Code Playgroud)

中间的:

m.mul(df['timestamp'], axis=0).where(m)

   var1  var2
0   NaN  10.0
1   NaN  20.0
2   NaN  30.0
3  10.0   NaN
4   NaN  20.0
5  30.0  30.0
6  10.0   NaN
7  20.0   NaN
8  30.0   NaN
Run Code Online (Sandbox Code Playgroud)