Pandas 使用第一个有效索引按组删除 nan

我正在使用以下数据框:


         Date    Id    Amount

   0    201301    1      nan

   1    201302    1      nan

   2    201303    1      100

   3    201304    1      120

   4    201305    1      nan

   5    201306    1      120

   6    201302    2      nan

   7    201303    2      150

   8    201304    2      180

我正在尝试获取Amountby的第一个有效索引Id。由于某种原因,这不起作用:


df.groupby('Id').Amount.first_valid_index()

我也在尝试这个:


df.groupby('Id').Amount.apply(lambda x: x.first_valid_index())

但是我的数据集是 20M+ 行,所以它花费的时间太长了,这对我不起作用。


有没有更快的方法来按组查找第一个索引?


我想要的输出是:


first_idx = [2,7]

甚至更好:


         Date    Id    Amount


   2    201303    1      100

   3    201304    1      120

   4    201305    1      nan

   5    201306    1      120

   7    201303    2      150

   8    201304    2      180

编辑:df.groupby('Id').Amount.apply(lambda x: x.first_valid_index())确实有效,但我觉得必须有一个更快的选择,问题似乎没有那么复杂。


慕姐8265434
浏览 76回答 2
2回答

幕布斯7119047

选项 1:仅获取第一个索引:df[df.Amount.notna()].groupby('Id').Date.idxmin()# 1.42 ms ± 14.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)输出:Id1    22    7Name: Date, dtype: int64选项 2:要获取其他行,请使用cumsumonnotna()df[df['Amount'].notna().groupby(df['Id']).cumsum().gt(0)]# 2.09 ms ± 220 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)选项3:您可以ffill()在组内选择未填写的:df[df.groupby('Id').Amount.ffill().notna()]# 831 µs ± 14.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)输出:     Date  Id  Amount2  201303   1   100.03  201304   1   120.04  201305   1     NaN5  201306   1   120.07  201303   2   150.08  201304   2   180.0结论:选项3是最快的!更新:使用选项 3 过滤两端:amt_group = df.groupby('Id').Amountdf[amt_group.bfill().notna() & amt_group.ffill().notna()]

jeck猫

.notnull使用+创建一个掩码.cumsum以获取组内第一个非空值之后的所有内容Amount。然后做一片。m = df.Amount.notnull().groupby(df.Id).cumsum().ge(1)df.loc[m]     Date  Id  Amount2  201303   1   100.03  201304   1   120.04  201305   1     NaN5  201306   1   120.07  201303   2   150.08  201304   2   180.0
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python