假设我具有以下数据框:
df = pd.DataFrame({"id": [1, 1, 1, 2, 2, 2], "date": [pd.Timestamp(2016, 7, 29), pd.Timestamp(2017, 8, 22), pd.Timestamp(2017, 10, 9), pd.Timestamp(2018, 1, 9), pd.Timestamp(2018, 3, 31), pd.Timestamp(2018, 7, 5)], "other_col": [11.1, 77.7, 22.2, 33.3, 44.4, 88.8]})
我想要实现的是删除每个组的最后N
行,其中data-frame is grouped by id
为N
为:具有date
的行数位于最后一行date
的3个月内(这将删除最后一行)。结果数据框应为:
r_df = pd.DataFrame({"id": [1, 2, 2], "date": [pd.Timestamp(2016, 7, 29), pd.Timestamp(2018, 1, 9), pd.Timestamp(2018, 3, 31)], "other_col": [11.1, 33.3, 44.4]})
答案 0 :(得分:1)
单个基于日期的lambda函数可以解决此问题。甚至不关心对行进行排序。
df.groupby('id').apply(
lambda x: x.loc[
x.date < (x.date.max() - pd.Timedelta(3, unit='M'))
]
).reset_index(drop=True)
更新:
正如@jpp所指出的,以下选择要快得多(约12倍):
df[df['date'] < (df.groupby('id')['date'].transform('max') - pd.Timedelta(3, unit='M'))]
作为额外的奖励,它还保留了原始顺序和索引。
答案 1 :(得分:0)
def remove_n_row(grouped_df):
last_row_date = grouped_df.iloc[-1]['date']
grouped_df_filtered = grouped_df[(grouped_df['date'] <=last_row_date) & (grouped_df['date'] <=last_row_date - timedelta(days=90))]
return grouped_df_filtered
from datetime import timedelta
r_df = df.groupby('id').apply(remove_n_row).reset_index(drop=True)
print(r_df)
输出
id date other_col
0 1 2016-07-29 11.1
1 2 2018-01-09 33.3
2 2 2018-03-31 44.4