【问题标题】:How to extract rows based on two conditions [duplicate]如何根据两个条件提取行[重复]
【发布时间】:2015-03-03 16:39:43
【问题描述】:

您好,我有一个数据集 d1。

import pandas as pd
d1 = {
'customers': pd.Series([1, 1, 1, 2, 2, 3, 3, 4, 4]),
'channel': pd.Series(['a', 'a', 'b', 'c', 'a', 'a', 'b', 'b', 'c']),
'freq': pd.Series([3, 3, 3, 2, 2, 2, 2, 2, 2])
}
d1=pd.DataFrame(d1)

我想获取仅使用过两个不同渠道的客户列表,并且渠道“a”是强制性的。

例如……第一个客户使用了两个不同的渠道“a”和“b”
第二个客户使用了“a”和“c”第三个客户使用了“a”和“b”。但是客户 4 没有使用通道 'a' 等等....

提前致谢

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这有点令人费解,但基本上我们使用 groupby、过滤和 2 级布尔索引对 df 执行乘法过滤:

    In [140]:
        d1[d1.customers.isin(d1[d1.channel=='a'].customers)].groupby('customers').filter(lambda x: x['channel'].nunique() == 2)
    Out[140]:
      channel  customers  freq
    0       a          1     3
    1       a          1     3
    2       b          1     3
    3       c          2     2
    4       a          2     2
    5       a          3     2
    6       b          3     2
    

    分解:

    In [141]:
    # filter out just those that have channel a
    d1[d1.channel=='a']
    Out[141]:
      channel  customers  freq
    0       a          1     3
    1       a          1     3
    4       a          2     2
    5       a          3     2
    In [144]:
    # we want these customer ids
    d1[d1.channel=='a'].customers
    Out[144]:
    0    1
    1    1
    4    2
    5    3
    Name: customers, dtype: int64
    In [146]:
    # perform an additional filtering so we only want customers who have channel a
    d1[d1.customers.isin(d1[d1.channel=='a'].customers)]
    Out[146]:
      channel  customers  freq
    0       a          1     3
    1       a          1     3
    2       b          1     3
    3       c          2     2
    4       a          2     2
    5       a          3     2
    6       b          3     2
    

    上面的内容然后在客户上分组,然后我们可以应用一个过滤器,其中唯一(nunique)客户的数量等于 2

    【讨论】:

      【解决方案2】:

      慢慢来,例如如果您打算进一步使过滤逻辑复杂化,这是一种替代方法(诚然不太优雅),它尽量不单线:

      def func(x):
          vals = x['channel'].value_counts()
          if 'a' in vals and len(vals) == 2:
              return True
          return False
      
      mask = d1.groupby('customers').apply(func)
      print mask
      

      输出:

      customers
      1             True
      2             True
      3             True
      4            False
      dtype: bool
      

      现在取决于您希望输出的方式:

      # Get a list of customers, like
      # [1, 2, 3]
      target_customers = [k for k, v in mask.to_dict().iteritems() if v]
      
      # Get a slice of the original DataFrame
      print d1[d1['customers'].isin(target_customers)]
      

      【讨论】:

        猜你喜欢
        • 2018-01-20
        • 1970-01-01
        • 2022-06-14
        • 2020-04-23
        • 1970-01-01
        • 2020-03-02
        • 1970-01-01
        • 2020-08-11
        • 1970-01-01
        相关资源
        最近更新 更多