Pandas 匹配多个列,并将匹配值作为单个新列获取

Con*_*est 3 python dataframe pandas

我有一个大约有 5 列的数据框。我希望匹配的值可能出现在最后 3 列中的任何一列中。

Key   |  col1   |  col2  |  col3 |  col4
----------------------------------------
1        abc       21        22      23
2        cde       22        21      20
3        fgh       20        22      23
4        lmn       20        22      21
Run Code Online (Sandbox Code Playgroud)

我正在过滤21最后三列中任何一列的值,如下所示:

df1 = df[(df['col2']=='21') | (df['col3']=='21') | (df['col4']=='21')]

这给了我

Key   |  col1   |  col2  |  col3 |  col4
----------------------------------------
1        abc       21        22      23
2        cde       22        21      20
4        lmn       20        22      21
Run Code Online (Sandbox Code Playgroud)

使用这个新的 df1 我想得到这个

Key   |  col1   |  newCol
-------------------------
1        abc       21      
2        cde       21      
4        lmn       21      
Run Code Online (Sandbox Code Playgroud)

基本上任何匹配的列都作为新的列值。我如何使用熊猫来做到这一点?我很感激你的帮助。所以我在想可能是我应该过滤并将它同时映射到新列,但我不知道如何?

Zer*_*ero 5

In [722]: df.loc[df[['col2', 'col3', 'col4']].eq(21).any(1), 
                 ['Key', 'col1']].assign(newcol=21)
Out[722]:
   Key col1  newcol
0    1  abc      21
1    2  cde      21
3    4  lmn      21
Run Code Online (Sandbox Code Playgroud)

细节

eq必要['col2', 'col3', 'col4']列的相等性检查

In [724]: df[['col2', 'col3', 'col4']].eq(21)
Out[724]:
    col2   col3   col4
0   True  False  False
1  False   True  False
2  False  False  False
3  False  False   True
Run Code Online (Sandbox Code Playgroud)

any 将返回行中是否有任何元素为 True

In [725]: df[['col2', 'col3', 'col4']].eq(21).any(1)
Out[725]:
0     True
1     True
2    False
3     True
dtype: bool
Run Code Online (Sandbox Code Playgroud)

用于.loc对匹配的行和必要的['Key', 'col1']列进行子集化。

In [726]: df.loc[df[['col2', 'col3', 'col4']].eq(21).any(1), ['Key', 'col1']]
Out[726]:
   Key col1
0    1  abc
1    2  cde
3    4  lmn
Run Code Online (Sandbox Code Playgroud)

并且,.assign(newcol=21)创建一个newcol列设置为21


jpp*_*jpp 2

这是一种方法。

import pandas as pd, numpy as np

df = pd.DataFrame([[1, 'abc', 21, 22, 23],
                   [2, 'cde', 22, 21, 20],
                   [3, 'fgh', 20, 22, 23],
                   [4, 'lmn', 20, 22, 21]],
                  columns=['Key', 'col1', 'col2', 'col3', 'col4'])

df2 = df[np.logical_or.reduce([df[col] == 21 for col in ['col2', 'col3', 'col4']])]\
        .assign(newCol=21)\
        .drop(['col2', 'col3', 'col4'], 1)

#    Key col1  newCol
# 0    1  abc      21
# 1    2  cde      21
# 3    4  lmn      21
Run Code Online (Sandbox Code Playgroud)

解释

  • 将整数存储为整数而不是字符串。
  • np.logical_or.reduce将您的|条件应用于列表理解。
  • assign使用过滤器值创建一个新列。
  • drop删除不需要的列,axis=1引用列。