我有一个包含两列的数据框:
import pandas as pd
data={'A':['x','y','z','r','x','z'],'B':[1,2,3,4,1,7]}
df=pd.DataFrame(data)
那让我:
A | B
x | 1
y | 2
z | 3
r | 4
x | 1
z | 7
然后是一个包含两个元素的列表的 n 列表:
list_of_lists=[['x',1],['x',4],['z',3],['y',1]]
我想确定每个子列表的 1st 元素是否与 A 列匹配,而第二个元素与 B 列匹配,像这样:
A | B | Match
x | 1 | True
y | 2 | False
z | 3 | True
r | 4 | False
x | 1 | True
z | 7 | False
应该为列表的每个元素创建两个列表,并在两个条件下都执行类似np.where的操作,但是必须有一种更简洁的方法。
答案 0 :(得分:3)
您可以尝试:
>>> df2 = pd.DataFrame(data = list_of_lists, columns = df.columns)
# less readable but slightly faster
# df2 = pd.DataFrame(dict(zip(['A','B'],zip(*list_of_lists))))
>>> df['Match'] = np.isin(df, df2).all(1)
>>> df
A B Match
0 x 1 True
1 y 2 False
2 z 3 True
3 r 4 False
4 x 1 True
5 z 7 False
答案 1 :(得分:3)
将DataFrame.merge
与辅助函数DataFrame
一起使用,并使用左联接和indicator = True参数,然后比较值both
:
df1 = df.merge(pd.DataFrame(list_of_lists, columns=df.columns), how='left', indicator=True)
df['Match'] = df1['_merge'].eq('both')
print (df)
A B Match
0 x 1 True
1 y 2 False
2 z 3 True
3 r 4 False
4 x 1 True
5 z 7 False
答案 2 :(得分:2)
您可以使用apply
方法:
df['Match'] = df.apply(lambda r: r.tolist() in list_of_lists, axis=1)
df
A B Match
0 x 1 True
1 y 2 False
2 z 3 True
3 r 4 False
4 x 1 True
5 z 7 False
要了解这一点,您可以执行一个中间步骤并检查结果:
df['temp'] = df.apply(lambda r: r.tolist(), axis=1)
df
A B temp
0 x 1 [x, 1]
1 y 2 [y, 2]
2 z 3 [z, 3]
3 r 4 [r, 4]
4 x 1 [x, 1]
5 z 7 [z, 7]
然后
df['Match'] = df.apply(lambda r: r['temp'] in list_of_lists, axis=1)
df
A B temp Match
0 x 1 [x, 1] True
1 y 2 [y, 2] False
2 z 3 [z, 3] True
3 r 4 [r, 4] False
4 x 1 [x, 1] True
5 z 7 [z, 7] False
答案 3 :(得分:2)
尝试一下:
df.apply(list, axis=1).apply(lambda x: True if x in list_of_lists else False)
0 True
1 False
2 True
3 False
4 True
5 False
dtype: bool
答案 4 :(得分:1)
我的方法:
我相信,即使匹配列表很大,这种方法也可以扩展(因此,逐个元素apply
可能很耗时,但是左联接是可以管理的)
# data
data='''A|B
x|1
y|2
z|3
r|4
x|1
z|7'''
with open("a.txt", 'w') as f:
print(data, file=f)
df1 = pd.read_csv("a.txt", sep="|")
list_of_lists=[['x',1],['x',4],['z',3],['y',1]]
# First, create a data frame of matches
matches = pd.DataFrame(list_of_lists, columns=['A', 'B'])
matches['Match'] = True
# left join with the original data, non-matches will be missing, so fill with False
df1.merge(matches, on=['A', 'B'], how='left').fillna(False)
输出:
A B Match
0 x 1 True
1 y 2 False
2 z 3 True
3 r 4 False
4 x 1 True
5 z 7 False