Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在多个列中查找匹配值并返回匹配的列标题_Python_Pandas_Match_Multiple Columns - Fatal编程技术网

Python 在多个列中查找匹配值并返回匹配的列标题

Python 在多个列中查找匹配值并返回匹配的列标题,python,pandas,match,multiple-columns,Python,Pandas,Match,Multiple Columns,我试图检查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

我试图检查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')....)
谢谢

我提出的解决方案

解释

我首先分配一个临时数据帧dd,所有列减去“min”列。我本可以把这些都放在一行中,但我相信这有助于提高可读性

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

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

dd.eq(df['min'], 0).dot(dd.columns)

0     A
1     C
2    AB
dtype: object
最后,我使用assign创建一个新的df副本,其中包含一个包含结果的新列。

我建议的解决方案

解释

我首先分配一个临时数据帧dd,所有列减去“min”列。我本可以把这些都放在一行中,但我相信这有助于提高可读性

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

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

dd.eq(df['min'], 0).dot(dd.columns)

0     A
1     C
2    AB
dtype: object
最后,我使用assign创建一个新的df副本,其中包含一个包含结果的新列

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
这是班轮

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

@Kay在本例中,eq是pd.DataFrame.eq,这是一种数据帧方法。第一个参数是self,它是数据帧本身,第二个参数是df['min']。所以a是dd,b是df['min']。但是,当第二个参数是一个系列而不是另一个数据帧时,pandas会将该系列与另一个dataframe的列对齐。我们需要将其改为与索引对齐,以便传递参数axis=0。如果我们刚刚做了dd==df['min'],我们就不能传递axis=0,所以我们使用方法表单。谢谢,这是有意义的。不确定我是否犯了一些错误,但这似乎不是我创造的。代码运行时没有bug tho。你知道为什么吗?谢谢@Kay,我经常使用assign,因为这是一种非侵入性的帮助方式。当您运行它时,它不会覆盖现有的数据帧,从而弄乱现有的数据帧。assign生成包含新列的副本。您有两个选择,通过覆盖变量名重新分配给df:df=df.assignwhich_col=dd.eqdf['min'],0.dotdd.columns。或者,直接将我在回答中避免的内容分配到一个新列,但欢迎您使用df['which_col']=dd.eqdf['min',0.dotdd。columns@piRSquared,这是一个非常优雅的解决方案@Kay在本例中,eq是pd.DataFrame.eq,这是一种数据帧方法。第一个参数是self,它是数据帧本身,第二个参数是df['min']。所以a是dd,b是df['min']。但是,当第二个参数是一个系列而不是另一个数据帧时,pandas会将该系列与另一个dataframe的列对齐。我们需要将其改为与索引对齐,以便传递参数axis=0。如果我们刚刚做了dd==df['min'],我们就不能传递axis=0,所以我们使用方法表单。谢谢,这是有意义的。不确定我是否犯了一些错误,但这似乎不是我创造的。代码运行时没有bug tho。你知道为什么吗?谢谢@Kay,我经常使用assign,因为这是一种非侵入性的帮助方式。当您运行它时,它不会覆盖现有的数据帧,从而弄乱现有的数据帧。assign生成包含新列的副本。您有两个选择,通过覆盖变量名重新分配给df:df=df.assignwhich_col=dd.eqdf['min'],0.dotdd.columns。或者,直接将我在回答中避免的内容分配到一个新列,但欢迎您使用df['which_col']=dd.eqdf['min',0.dotdd。columns@piRSquared,这是一个非常优雅的解决方案!