使用Pandas的.isin()进行布尔索引未返回预期结果的问题求助
使用Pandas的.isin()进行布尔索引未返回预期结果的问题求助
嗨,我来帮你捋清楚这个问题~
首先得说清楚你原来的代码为什么没得到预期结果:
你写的couples['man'][~couples['man'].isin(couples['woman'])]里,isin()的逻辑是检查整个man的爱好列表是否存在于couples['woman']这一列的所有列表中,而不是拿当前行的man爱好和同一行的woman爱好做元素级别的对比。比如第一行的man列表['fishing', 'biking', 'reading']并不存在于woman列的任何一个列表里,所以~isin()返回True,直接把整个man列表保留下来了,这显然不是你要的“找出单个爱好差异”的效果。
要实现“每行独立对比,找出一方有而另一方没有的爱好”,咱们可以用Pandas的apply()方法逐行处理,结合集合的差集操作来做——集合求差集正好就是找“我有你没有”的元素,非常顺手。
解决代码示例
import numpy as np import pandas as pd couples = pd.DataFrame({ 'man': [ ['fishing', 'biking', 'reading'], ['hunting', 'mudding', 'fishing'], ['reading', 'movies', 'running'], ['running', 'reading', 'biking', 'mudding'], ['movies', 'reading', 'yodeling'] ], 'woman': [ ['biking', 'reading', 'movies'], ['fishing', 'drinking'], ['knitting', 'reading'], ['running', 'biking', 'fishing', 'movies'], ['movies'] ] }) # 计算男人有但妻子没有的爱好 couples['man_only_hobbies'] = couples.apply( lambda row: list(set(row['man']) - set(row['woman'])), axis=1 ) # 计算女人有但丈夫没有的爱好 couples['woman_only_hobbies'] = couples.apply( lambda row: list(set(row['woman']) - set(row['man'])), axis=1 ) print(couples)
运行结果
man woman man_only_hobbies woman_only_hobbies 0 [fishing, biking, reading] [biking, reading, movies] [fishing] [movies] 1 [hunting, mudding, fishing] [fishing, drinking] [hunting, mudding] [drinking] 2 [reading, movies, running] [knitting, reading] [movies, running] [knitting] 3 [running, reading, biking, mudding] [running, biking, fishing, movies] [reading, mudding] [fishing, movies] 4 [movies, reading, yodeling] [movies] [reading, yodeling] []
补充说明
- 用
set()转换是因为集合支持快速的差集运算,效率比手动遍历列表高很多; - 如果需要保留原爱好列表的顺序,可以不用集合,改用列表推导式筛选:
couples['man_only_hobbies'] = couples.apply( lambda row: [hobby for hobby in row['man'] if hobby not in row['woman']], axis=1 )
这样结果会严格遵循原列表里的爱好顺序,比如第一行还是['fishing'],和集合方法的结果一致,只是顺序保留了原始排列。
备注:内容来源于stack exchange,提问作者katjacodes
相关产品推荐
相关产品推荐

