使用Pandas求两个DataFrame交集结果异常,寻求技术支持
问题:两个基因列表交集计算结果不符合预期
尝试找出两个大型基因列表(nofilt_0与dub_0,实际各含23192行)的共同元素,但运行代码后返回所有行均匹配,而手动文本对比显示仅部分元素重合。以下是使用的代码:
import numpy as np import pandas as pd import scanpy as sc import seaborn as sns import matplotlib.pyplot as plt nofilt_0 = ['LINC02295', 'AL596202.1', 'TAS2R5', 'NOG', 'AL161644.1', 'AL163932.1', 'PIGY-DT', 'LINC01193', 'PLA2G4C', 'GLIS3', 'AC079779.1', 'LINC00501', 'NPAS2', 'SIAH3', 'AC118658.1', 'Z98745.2', 'AC007785.3', 'WARS2-IT1', 'TMEM132E', 'GPC2', 'AL132801.1', 'SLC22A17', 'AC092115.2', 'MMP28', 'SORCS3', 'LINC02714', 'AADACL2-AS1', 'AP000345.2', 'AC138819.1', 'AC099066.1', 'NUPR2', 'AC090018.2', 'DSC1', 'GOLGA6L7', 'AL390866.1', 'CCR7', 'AC112254.1', 'SLC22A31', 'AL442003.1', 'ME1', 'AC013270.1', 'SLC22A10', 'AL449214.1', 'AC022023.2', 'AC096719.1', 'DBX1', 'SSTR3', 'LRRN3', 'FGF17', 'CAV3', 'AL117350.1', 'SEMA3A', 'GABRB3', 'AC008686.1', 'CNNM1', 'SV2B', 'AC001226.1', 'LMOD2', 'DACT1', 'AKR1C1', 'AC129507.1', 'SGCG', 'CHRNG', 'AL109936.2', 'AL157936.1', 'EPAS1', 'AC093599.1', 'FAM83F', 'AP000238.1', 'AC117500.1', 'AC022113.1', 'CGN', 'ACTN1-AS1', 'AC004067.1', 'F11', 'AC007786.1', 'ADTRP', 'AL035252.2', 'CAPSL', 'AC018809.1', 'AC022445.1', 'AC069287.3', 'AL391097.1', 'ASB9', 'PRRT1', 'AC104463.2', 'AL118511.3', 'AL590999.1', 'AC090515.6', 'AC019080.5', 'IGLV1-36', 'A1CF', 'MYO1F', 'AL512452.1', 'ASIC2', 'AC008496.2', 'TEAD3', 'TMEM273', 'DMRTC1', 'LAMC3', 'RASGEF1A', 'AC005899.5', 'PNMA8B', 'AC021148.2', 'AL020997.5', 'SHCBP1L', 'AC069029.1', 'AC092068.2', 'PRR5L', 'AL732437.2', 'SLAMF7', 'LCTL', 'BFSP1', 'AC023794.2', 'GJC3', 'RSPH10B', 'CA6', 'ZNF662', 'AL138686.1', 'RND2', 'FAM242C', 'ANXA2', 'SLC22A13', 'FAM181B', 'IL10', 'AL662907.3', 'ASCL2', 'AC004988.1', 'TUSC1', 'AC109460.4', 'DGKB', 'AC009244.2', 'ACVR2B-AS1', 'PKP3', 'NIBAN1', 'NOXO1', 'MSLNL', 'AP001627.1', 'REG4', 'AC092794.1', 'AC097641.2', 'ALOX15', 'AC139491.4', 'ADAMTSL2', 'DDC', 'AL049557.1', 'RNF144A-AS1', 'IFITM10', 'AC009053.3', 'RAB9B', 'RAI2', 'AC103563.9', 'GIMD1', 'LINC01030', 'ADGRA3', 'AC074044.1', 'AL133445.3', 'CD58', 'AC004477.1', 'IL12A-AS1', 'AC089983.1', 'AC024588.1', 'MTTP', 'TRAJ11', 'AL161729.2', 'CASR', 'AADACL2', 'AL133387.1', 'AL807776.1', 'FREM3', 'AL021918.3', 'AL845472.1', 'AC009041.2', 'IGKV2-29', 'AL359764.3'] dub_0 =['DUSP4', 'AC017002.3', 'LINC02804', 'GML', 'GNAO1', 'AC025946.1', 'TGFBR3L', 'EDN3', 'TMEM200A', 'MSC-AS1', 'ZP1', 'MSC', 'AC090515.6', 'LINC00892', 'HAS3', 'PLSCR2', 'SLC44A3', 'AC013460.1', 'CNTNAP1', 'TMPRSS11E', 'LINC01229', 'WDR17', 'TNFRSF18', 'LINC02295', 'EFNA5', 'AC074366.1', 'AL391056.1', 'ADAMTSL4', 'EPGN', 'APOBEC3H', 'IRAIN', 'CXCR6', 'LINC01498', 'WDR86-AS1', 'TSSK6', 'A1CF', 'CPHXL', 'IGLV7-46', 'AC087473.1', 'AC096577.1', 'AL590550.1', 'TP63', 'AC016866.1'] df = pd.DataFrame(nofilt_0, columns =['markers']) df1 = pd.DataFrame(dub_0, columns = ['markers']) int_df = pd.merge(df,df1, how='inner') # intersection df1[~df1.isin(df)] #not intersecting
问题分析与解决方法
1. 先确认交集的真实数量
先打印int_df的长度,验证是否真的全匹配:
print("交集行数:", len(int_df))
在你提供的示例数据中,正确交集应为LINC02295、AC090515.6、A1CF这3个元素。如果真实数据返回全匹配,大概率是元素存在隐形字符(如前后空格、换行符、制表符),文本对比网站会忽略这些隐形字符判定为不同,但Pandas会严格匹配字符(包括隐形字符),导致结果异常。
2. 修正非交集元素的提取代码
当前df1[~df1.isin(df)]的写法存在问题:isin作用于整个DataFrame时返回布尔矩阵,直接索引会得到带NaN的无效结果。正确提取非交集元素的写法是:
# 提取df1中不在df里的元素 non_intersect = df1[~df1['markers'].isin(df['markers'])] # 重置索引(可选) non_intersect = non_intersect.reset_index(drop=True)
3. 清洗元素中的隐形字符
对两个列表的元素做清洗,去除前后空白字符:
# 清洗列表元素 nofilt_0_clean = [x.strip() for x in nofilt_0] dub_0_clean = [x.strip() for x in dub_0] # 转成DataFrame重新计算交集 df_clean = pd.DataFrame(nofilt_0_clean, columns=['markers']) df1_clean = pd.DataFrame(dub_0_clean, columns=['markers']) int_df_clean = pd.merge(df_clean, df1_clean, how='inner')
4. 用集合快速验证交集结果
Python原生集合可以快速计算交集,对比Pandas结果是否一致:
set_nofilt = set(nofilt_0_clean) set_dub = set(dub_0_clean) intersection_set = set_nofilt & set_dub print("集合交集元素数量:", len(intersection_set)) print("交集元素:", sorted(intersection_set))
如果集合结果和文本对比网站一致,说明是元素的隐形字符导致Pandas匹配异常,清洗后即可解决。
5. 处理重复元素(可选)
如果列表中存在重复元素,merge会返回所有匹配的重复行,可先去重:
df_clean = df_clean.drop_duplicates(subset='markers') df1_clean = df1_clean.drop_duplicates(subset='markers')
内容的提问来源于stack exchange,提问作者Caroline
相关产品推荐
相关产品推荐

