【问题标题】:Python Groupby Separate Filter for Each GroupPython Groupby 每个组的单独过滤器
【发布时间】:2022-01-23 23:54:58
【问题描述】:

假设我有以下数据框:

import pandas as pd

d = {'id':  [1, 2, 3, 3, 3, 2, 2, 1, 2, 3, 2, 3],
 'date': [1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4],
 'product': ['a', 'a', 'b', 'a', 'b', 'a', 'b', 'c', 'b', 'c', 'c', 'c']}

df = pd.DataFrame(d)

我想保留每个 ID 在他们购买产品“b”当天和之后的所有数据,并在他们购买产品“b”之前删除所有数据。 ID 1 没有数据,因为他们没有购买产品,ID 2 有第 3 天和第 4 天的数据,ID 3 有第 1-4 天的数据。

我知道我可以按 id 分组,然后从各个组中过滤行,但我不知道如何根据组使过滤器动态化。我试过循环遍历这些组,但速度很慢(现在我有 19,000 个 ID,但它只会随着我继续项目而增长)。

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 能否请您展示您的预期输出示例?这将有助于可视化很多。谢谢你:)

标签: python pandas dataframe filter


【解决方案1】:

这是另一个解决方案:groupby + 自定义函数

def get_data(x):
    idx = np.where(x['product']=='b')[0]
    if idx.size:
        return x[idx[0]:]

out = df.groupby('id').apply(get_data).droplevel(0).sort_index()

输出:

    id  date product
2    3     1       b
3    3     2       a
4    3     2       b
6    2     3       b
8    2     3       b
9    3     3       c
10   2     4       c
11   3     4       c

【讨论】:

  • 谢谢!我知道可能有这样的解决方案,但仍然遇到 apply() 的一些问题。现在我看到使用 apply() 和 groupby 将每个单独的组传递给函数。
【解决方案2】:

您可以使用eq 选择产品“b”,并使用groupby+cummax 将连续行设置为每组 True。然后切片数据帧

df[df['product'].eq('b').groupby(df['id']).cummax()]

输出:

    id  date product
2    3     1       b
3    3     2       a
4    3     2       b
6    2     3       b
8    2     3       b
9    3     3       c
10   2     4       c
11   3     4       c

注意。这假设数据框按日期排序。如果不使用sort_values(by='date')(或by=['group', 'date']

【讨论】:

  • 谢谢!你能帮我理解为什么 cummax() 返回所有连续的行吗?如果我从左到右阅读上面的内容,似乎连续的行已经从 eq() 中消失/过滤掉了。
  • cummax 会将False 后面的所有True 转换为True,从而保留行
猜你喜欢
  • 2013-07-10
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多