【问题标题】:look for match values in multiple columns and return the matched column head在多列中查找匹配值并返回匹配的列标题
【发布时间】:2017-07-21 19:14:27
【问题描述】:

我正在尝试检查哪一列(在 3 列中)在列 min 中包含相同的值,并返回匹配列的列标题。用np.where就可以了,那我需要手动输入条件并比较列,这样做有没有更优雅的?

输入示例:

 A    B   C   min    
 1    2   3   1      
 2    3   6   6      
 2    2   1   2      

输出示例:

 A    B   C   min    which_col
 1    2   3   1      A
 2    3   6   6      C
 2    2   1   2      AB

我可以使用:

np.where(df['min']==df['A'], 'A', np.where(df['min']==df['B'], 'B')....)

谢谢!

【问题讨论】:

    标签: python pandas match multiple-columns


    【解决方案1】:

    我提出的解决方案

    dd = df.drop('min', 1)
    df.assign(which_col=dd.eq(df['min'], 0).dot(dd.columns))
    
       A  B  C  min which_col
    0  1  2  3    1         A
    1  2  3  6    6         C
    2  2  2  1    2        AB
    

    说明

    我首先分配一个临时数据框dd,其中所有列都减去'min' 列。我本可以将所有内容集中在一行中,但我相信这有助于提高可读性。

    dd = df.drop('min', 1)
    

    接下来,我将'min' 列与dd 进行比较。但是为了比较df['min'] 的每个元素与dd 的每一行,我需要将axis=0 参数传递给eq 方法

    dd.eq(df['min'], 0)
    
           A      B      C
    0   True  False  False
    1  False  False   True
    2   True   True  False
    

    如果我在点积中使用此结果,它将自动转换为 int,因此 False 变为 0 并且 True 变为 1。当我使用ddcolumns 作为另一个操作数时,点积的求和方面会自动连接列中匹配的字符串。

    dd.eq(df['min'], 0).dot(dd.columns)
    
    0     A
    1     C
    2    AB
    dtype: object
    

    最后,我使用assign 创建df 的新副本,其中包含一个包含结果的新列。

    【讨论】:

    • @Kay 在这种情况下,eqpd.DataFrame.eq,这是一种数据帧方法。第一个参数是self,它是数据框本身,第二个参数是df['min']。所以addbdf['min']。但是,当第二个参数是一个系列而不是另一个数据框时,pandas 会将该系列与另一个数据框的列对齐。我们需要将其更改为与索引对齐,因此我们传递参数axis=0。如果我们刚刚完成了dd == df['min'],我们就无法通过axis=0,所以我们使用方法形式来代替。
    • 谢谢,这是有道理的。不确定我是否犯了一些错误,但 columnwhich_col 似乎没有创建。代码运行没有错误。你知道为什么吗?谢谢!
    • @Kay,我经常使用assign,因为它是一种非侵入性的帮助方式。当你运行它时,它不会通过覆盖它来搞乱你现有的数据框。 assign 生成一个副本,其中包含一个新列。您有两个选择,通过覆盖变量名重新分配给dfdf = df.assign(which_col=dd.eq(df['min'], 0).dot(dd.columns))。或者,直接分配给一个新列(我在回答中避免这样做,但欢迎您这样做)df['which_col'] = dd.eq(df['min'], 0).dot(dd.columns)
    • @piRSquared,这是一个非常优雅的解决方案!
    【解决方案2】:

    这是一个班轮。

    In [138]: (df[list('ABC')].eq(df['min'], axis=0)
               .apply(lambda x: ''.join(x[x].index), axis=1))
    Out[138]:
    0      A
    1      C
    2    AB
    dtype: object
    
    In [139]: df['which_col'] = (df[list('ABC')].eq(df['min'], axis=0)
                                 .apply(lambda x: ''.join(x[x].index), axis=1))
    
    In [140]: df
    Out[140]:
       A  B  C  min which_col
    0  1  2  3    1         A
    1  2  3  6    6         C
    2  2  2  1    2        AB
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      相关资源
      最近更新 更多