【问题标题】:Check if column value is in other columns in pandas检查列值是否在熊猫的其他列中
【发布时间】:2017-03-29 12:22:18
【问题描述】:

我在 pandas 中有以下数据框

  target   A       B      C
0 cat      bridge  cat    brush  
1 brush    dog     cat    shoe
2 bridge   cat     shoe   bridge

如何测试df.target 是否在['A','B','C', etc.] 的任何列中,其中有很多列要检查?

我尝试将 A、B 和 C 合并成一个字符串以使用 df.abcstring.str.contains(df.target),但这不起作用。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用dropisinany

    • drop target 列与您的 ABC 列只有一个 df
    • 检查isin的值是否为目标列
    • 并检查是否存在any 命中

    就是这样。

    df["exists"] = df.drop("target", 1).isin(df["target"]).any(1)
    print(df)
    
        target  A       B       C       exists
    0   cat     bridge  cat     brush   True
    1   brush   dog     cat     shoe    False
    2   bridge  cat     shoe    bridge  True
    

    【讨论】:

    • 次要:“isin”是一个不幸的列名,因为它也是 DataFrame 方法的名称。
    • @Minor 你说得对,谢谢你的评论。已编辑。
    • 想想看,.isin(df["target"]).eq(df["target"], 0) 的替代品。但基本等价。
    【解决方案2】:

    如果需要按行检查,您可以使用eq 删除列pop

    mask = df.eq(df.pop('target'), axis=0)
    print (mask)
           A      B      C
    0  False   True  False
    1  False  False  False
    2  False  False   True
    

    然后如果需要检查至少一个True 添加any:

    mask = df.eq(df.pop('target'), axis=0).any(axis=1)
    print (mask)
    0     True
    1    False
    2     True
    dtype: bool
    
    df['new'] = df.eq(df.pop('target'), axis=0).any(axis=1)
    print (df)
            A     B       C    new
    0  bridge   cat   brush   True
    1     dog   cat    shoe  False
    2     cat  shoe  bridge   True
    

    但如果需要检查列中的所有值,请使用isin:

    mask = df.isin(df.pop('target').values.tolist())
    print (mask)
           A      B      C
    0   True   True   True
    1  False   True  False
    2   True  False   True
    

    如果要检查所有值是否为True,请添加all

    df['new'] = df.isin(df.pop('target').values.tolist()).all(axis=1)
    print (df)
            A     B       C    new
    0  bridge   cat   brush   True
    1     dog   cat    shoe  False
    2     cat  shoe  bridge  False
    

    【讨论】:

    • 我喜欢 pop 的用法,但它实际上改变了原来的 df 就地删除了 target 列。这可能是一些意想不到的副作用。
    • 我认为这里更好pop,这取决于OP需要什么。
    【解决方案3】:

    OneHotEncoder 方法:

    In [165]: x = pd.get_dummies(df.drop('target',1), prefix='', prefix_sep='')
    
    In [166]: x
    Out[166]:
       bridge  cat  dog  cat  shoe  bridge  brush  shoe
    0       1    0    0    1     0       0      1     0
    1       0    0    1    1     0       0      0     1
    2       0    1    0    0     1       1      0     0
    
    In [167]: x[df['target']].eq(1).any(1)
    Out[167]:
    0    True
    1    True
    2    True
    dtype: bool
    

    解释:

    In [168]: x[df['target']]
    Out[168]:
       cat  cat  brush  bridge  bridge
    0    0    1      1       1       0
    1    0    1      0       0       0
    2    1    0      0       0       1
    

    【讨论】:

      【解决方案4】:

      另一种使用索引的方法difference方法:

      matches = df[df.columns.difference(['target'])].eq(df['target'], axis = 0)
      
      #       A      B      C
      #0  False   True  False
      #1  False  False  False
      #2  False  False   True
      
      # Check if at least one match:
      matches.any(axis = 1)
      
      #Out[30]: 
      #0     True
      #1    False
      #2     True
      

      如果您想查看哪些列符合目标,这里有一个可能的解决方案:

      matches.apply(lambda x: ", ".join(x.index[np.where(x.tolist())]), axis = 1)
      
      Out[53]: 
      0    B
      1     
      2    C
      dtype: object
      

      【讨论】:

        【解决方案5】:

        您可以对每一行应用一个函数来计算与“目标”列中的值匹配的值的数量:

        df["exist"] = df.apply(lambda row:row.value_counts()[row['target']] > 1 , axis=1)
        

        对于看起来像这样的数据框:

           b  c target
        0  3  a      a
        1  3  4      2
        2  3  4      2
        3  3  4      2
        4  3  4      4
        

        输出将是:

           b  c target  exist
        0  3  a      a   True
        1  3  4      2  False
        2  3  4      2  False
        3  3  4      2  False
        4  3  4      4   True
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-14
          • 1970-01-01
          • 2021-09-02
          • 1970-01-01
          • 1970-01-01
          • 2019-03-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多