Python 熊猫匹配多个列,并将匹配值作为单个新列获取
我有一个大约有5列的数据框。我希望匹配的值可以出现在最后3列中Python 熊猫匹配多个列,并将匹配值作为单个新列获取,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个大约有5列的数据框。我希望匹配的值可以出现在最后3列中 Key | col1 | col2 | col3 | col4 ---------------------------------------- 1 abc 21 22 23 2 cde 22 21 20 3 fgh 20 22 23 4 lmn
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
我对最后三列中的任何一列的值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
使用这个新的df1,我想得到这个
Key | col1 | newCol
-------------------------
1 abc 21
2 cde 21
4 lmn 21
基本上任何匹配的列都可以作为新列的值。我如何使用熊猫来实现这一点?我感谢你的帮助。所以我想可能我应该同时过滤并将其映射到新列,但我不知道如何使用
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
细节 在必要的
['col2'、'col3'、'col4']列上进行等式检查eq
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
any
将返回行中任何元素是否为True
In [725]: df[['col2', 'col3', 'col4']].eq(21).any(1)
Out[725]:
0 True
1 True
2 False
3 True
dtype: bool
使用.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
并且,.assign(newcol=21)
创建一个newcol
列,设置为21
,这里是一种方法
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
解释
- 将整数存储为整数而不是字符串
np.logical_或.reduce
在列表中应用您的
条件
assign
使用筛选值创建一个新列
drop
删除不需要的列,axis=1
指列
正如jpp所指出的,这里有两种可能性:21和22在所有3列中都很常见。假设您不知道真正要查找的是哪一列,您可以使用set()
来隔离每列的唯一值,然后使用set.intersection()
来查找共性:
df = pd.DataFrame([{'col1':'a', 'col2':21, 'col3':22, 'col4':23},
{'col1':'b', 'col2':22, 'col3':21, 'col4':20},
{'col1':'c', 'col2':20, 'col3':22, 'col4':21},
{'col1':'d', 'col2':21, 'col3':21, 'col4':22}])
s1 = set(df['col2'].values)
s2 = set(df['col3'].values)
s3 = set(df['col4'].values)
df['new_col'] = str(s1.intersection(s2, s3))
df
col1 col2 col3 col4 new_col
a 21 22 23 {21, 22}
b 22 21 20 {21, 22}
c 20 22 21 {21, 22}
d 21 21 22 {21, 22}
从第二个数据帧中,您如何知道过滤了哪个值?在本例中,它可能是21或22。如果您知道匹配的值,为什么不能创建新列作为此值?或者,您是否要求提取3个结果列中存在的公共值(不知道它是'21')?对,我不知道是哪一个。所以我想我应该同时过滤并映射到新的专栏,但我不知道怎么做?这两种方法都有效,但我只能接受一种。接受这个解释。我将从@Zero向上投票另一个答案。我非常感谢你的帮助。imho-这绝对是最好的答案-如果有更多的解释-那太好了:)