【问题标题】:Find rows where one of 2 cols contains any value from a third split column in Pandas查找其中 2 个 cols 之一包含 Pandas 中第三个拆分列中的任何值的行
【发布时间】:2018-05-12 05:30:16
【问题描述】:

给定一个像这样的 Pandas 数据框:

A           B           C
-------------------------
A. b.       b. d.       a
c.          c.          d
a. k.       b.          b
a.          b.          a, B

代码:

df = pd.DataFrame({
    'A': ['A. b.', 'c.', 'a. k.', 'a.'],
    'B': ['b. d.', 'c.', 'b.', 'b.'],
    'C': ['a', 'd', 'b', 'a, B']
})

我想选择 A 或 B 包含 C 中的任何值的所有行。这里的结果是:

A           B           C
-------------------------
A. b.       b. d.       a
a. k.       b.          b
a.          b.          a, B

所有单元格都包含简单分隔格式的值(可以使用split)。

我试过了:

df[df['A'].str.contains(df['C'].split(','))]

但目前没有成功。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    从您的示例输出中假设您的比较不区分大小写:

    mask = pd.DataFrame({
               'AB': (df.A + df.B).str.lower().map(set),
               'C': df.C.str.split(',').map(set)
           }).apply(lambda row: bool(row['AB'].intersection(row['C'])), axis=1)
    
    df[mask].reset_index(drop=True)
    

    说明:

    合并列AB,并将每个单元格值转换为其包含的一组字符。将列 C 分隔值也拆分为一组,并检查 ABC 之间的交集是否为空,使用生成的 bool 系列作为原始数据框的掩码。


    时间安排:

    def f():
        mask = pd.DataFrame({
                   'AB': (df.A + ' ' + df.B).str.lower().map(set),
                   'C': df.C.str.split(',').map(set)
               }).apply(lambda row: bool(row['AB'].intersection(row['C'])), axis=1)
    
        df[mask].reset_index(drop=True)
    
    %timeit f
    

    输出:

    27.4 ns ± 0.483 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
    

    【讨论】:

      【解决方案2】:

      我想选择 A 或 B 包含 C 中的任何值的所有行

      您可以在此处使用.isin()。这是一个小例子:

      df1 = pd.DataFrame([[1,4,1], [2,5,4], [3,6,7]], columns=['a','b','c'])
      df1.loc[df1['a'].isin(df1['c'])]
      
      #output:
      
          a   b   c
      0   1   4   1
      

      之所以返回行是确实是因为值1 在列c 中。

      【讨论】:

      • 这对我不起作用:df = pd.DataFrame({ 'A': ['A.b.', 'c.', 'ak', 'a.'], ' B': ['bd', 'c.', 'b.', 'b.'], 'C': ['a', 'd', 'b', 'a, B'] }) 使用你的代码: df.loc[df['C'].isin(df['A'])]
      • @Zubo,当然 - 在 cmets 中的示例中有 .。你将不得不删除那些。因为'a' != 'a.'在你的问题中你已经证明了.split()的知识
      • 我也试过df.loc[df['C'].str.split(',').isin(df['A'])],它返回TypeError: unhashable type: 'list'。此外,我无法从您的示例中看到如何包含C 中的任何内容都可以在 A C 中的条件。如果可以使用它,我很乐意再次支持您的答案。
      • @Zubo。你可以编辑你的问题吗?我对你需要什么感到困惑。但是,如果您的问题得到了另一个帖子的回答,那么您可以保留它并接受另一个答案
      猜你喜欢
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多