Pandas列表处理:生成DataFrame差集列及NaN替换问题
解决DataFrame生成差集列及NaN替换失效问题
嘿,我刚好之前也碰到过类似的情况,这就帮你搞定这两个需求——生成resultPIDs列,还有解决fillna()替换NaN为空列表无效的问题。
为啥fillna([])没效果?
其实是Pandas的小坑:fillna()默认是用来处理标量缺失值的,而列表属于对象类型,直接用df['MPIDs'].fillna([])的话,Pandas没法把填充逻辑应用到对象列上,所以才会失效。得换个方式处理。
完整解决方案代码
import pandas as pd from pandas import NaN # 先还原你的示例DataFrame data = { 'mAID': ['A', 'B', 'A', 'A'], 'MAID': ['D', 'E', 'E', 'F'], 'mPIDs': [['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z']], 'MPIDs': [['X', 'W', 'L'], ['Y', 'Z', 'W'], ['Y', 'Z', 'W'], NaN] } df = pd.DataFrame(data) # 第一步:把MPIDs里的NaN换成空列表 df['MPIDs'] = df['MPIDs'].apply(lambda x: x if isinstance(x, list) else []) # 第二步:生成resultPIDs,取mPIDs有但MPIDs没有的元素 df['resultPIDs'] = df.apply( lambda row: [pid for pid in row['mPIDs'] if pid not in row['MPIDs']], axis=1 ) # 如果需要把列表转成逗号分隔的字符串,就加这行(可选) # df['resultPIDs'] = df['resultPIDs'].apply(lambda x: ','.join(x)) print(df)
代码拆解说明
替换NaN为空列表:
用apply()加lambda函数,逐个检查MPIDs的元素——如果是列表就保留,不是的话(也就是NaN)就换成空列表[],这样就能正确处理对象列的缺失值了。生成差集列:
还是用apply()按行处理,遍历mPIDs里的每个元素,筛出不在MPIDs里的,凑成新列表就是resultPIDs的值。
运行后的结果
mAID MAID mPIDs MPIDs resultPIDs 0 A D [X, Y, Z] [X, W, L] [Y, Z] 1 B E [X, Y, Z] [Y, Z, W] [X] 2 A E [X, Y, Z] [Y, Z, W] [X] 3 A F [X, Y, Z] [] [X, Y, Z]
大数据量优化方案
如果你的数据行数特别多,apply()的速度可能有点慢,可以换成列表推导式,效率会高不少:
# 先处理MPIDs的NaN mpids_clean = [x if isinstance(x, list) else [] for x in df['MPIDs']] # 批量计算差集 df['resultPIDs'] = [[p for p in m_pid if p not in mp_pid] for m_pid, mp_pid in zip(df['mPIDs'], mpids_clean)]
这样处理几十万行数据也不会卡~
内容的提问来源于stack exchange,提问作者BKS
相关产品推荐
相关产品推荐

