Pandas如何判断列中集合是否为另一列集合的子集?
解决Pandas中集合列的子集判断问题(兼顾性能)
嘿,我来帮你搞定这个问题!咱们先拆解下你遇到的两个核心点:报错原因和大场景下的性能优化。
1. 为什么你的lambda代码报错?
你之前写的df.apply(lambda x:x.set1.issubset(x.set2))没有指定axis=1参数,默认情况下apply是按列来处理的,这时候x代表的是每一列的Series对象,而不是单行数据,自然就找不到set1这个属性啦。
2. 基础可行的解决方案
只需要给apply加上axis=1,让它按行处理,这样x就代表每一行数据,就能正常访问set1和set2列的集合了:
import pandas as pd # 你的示例DataFrame df = pd.DataFrame([[{1,2,3,'a'},{5,'b','d',1,4}], [{'z',9,'a','b',3},{'a',3,'z','b','d',9,4}]], columns=['set1','set2']) # 新增issubset列 df['issubset'] = df.apply(lambda row: row['set1'].issubset(row['set2']), axis=1)
运行后你会得到预期的结果:
| set1 | set2 | issubset |
|---|---|---|
| {1, 2, 3, 'a'} | {1, 4, 5, 'b', 'd'} | False |
| {'a', 3, 'b', 9, 'z'} | {'a', 3, 4, 'b', 9, 'd', 'z'} | True |
3. 大场景下的性能优化
虽然上面的代码能解决问题,但apply(axis=1)本质是Python层面的逐行循环,当你有数千行+上万元素的集合时,效率会比较低。更高效的方式是用列表推导式直接遍历两列的元素,它避免了apply带来的额外开销,速度能提升不少:
df['issubset'] = [s1.issubset(s2) for s1, s2 in zip(df['set1'], df['set2'])]
这个方法的原理是直接把set1和set2列的集合一一配对,然后调用集合的issubset方法,完全是原生Python循环,比apply快2-5倍(具体取决于数据规模)。
为什么这个方法更高效?
Pandas的apply(axis=1)在处理每行时,会额外做一些数据包装和函数调用的工作,而列表推导式是直接操作底层的Python对象,没有这些额外开销,对于大规模数据来说,性能差异会很明显。
内容的提问来源于stack exchange,提问作者clg4
相关产品推荐
相关产品推荐

