Pandas提取指定元素成对对比结果数量不符的排查求助
Pandas筛选query-reference成对对比结果不足的问题排查
我有一个包含query与reference成对对比、距离列及元数据的Pandas DataFrame,已从主DataFrame筛选得到新的DataFrame。现在想要获取新DataFrame的query列中19个元素的所有成对对比(即其中一个元素在主DataFrame的query列,另一个在reference列)。
使用Python 3.10.6与Pandas 1.5.0编写了如下函数:
def metadata_def_epi(df_metadata, df_selection_ur): df_selection_ur_list = df_selection_ur["query"].values.tolist() mask = df_metadata["query"].isin(df_selection_ur_list) & df_metadata["reference"].isin(df_selection_ur_list) df_out = df_metadata[mask] return df_out
函数可正常运行,但仅得到136组成对对比,而按公式n(n-1)/2计算(n=19)预期应为171组,请问遗漏了什么?
补充数据示例
主DataFrame结构与部分数据
| FIELD1 | query | reference | Core | Accessory | pmatch | patient_id_query | Collection_date_query | instelling_query | locatie_query | afdeling_query | patient_id_reference | Collection_date_reference | instelling_reference | locatie_reference | afdeling_reference | Cdate_query | Cdate_reference | epi_link_id | snp |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ASM1421713v1_genomic | ASM1527755v1_genomic | 0,000312388 | 0,052548587 | 0,938905646 | pt4 | 17-aug-2020 | AP | 00 | 00 | pt5 | 7-nov-2020 | HK | 00 | 00 | 17-aug-2020 | 7-nov-2020 | Unrelated | 70 |
| 1 | ASM1421713v1_genomic | ASM1930313v1_genomic | 0,002514303 | 0,15178698 | 0,788494326 | pt4 | 17-aug-2020 | AP | 00 | 00 | pt6 | 21-jul-2021 | LA | 00 | 00 | 17-aug-2020 | 21-jul-2021 | Unrelated | 3608 |
| 2 | ASM1421713v1_genomic | ASM194037v1_genomic | 0,000102997 | 0,080629885 | 0,916627997 | pt4 | 17-aug-2020 | AP | 00 | 00 | pt2 | 9-jan-2017 | CP | 00 | 00 | 17-aug-2020 | 9-jan-2017 | Unrelated | 103 |
| 3 | ASM1421713v1_genomic | ASM2008964v1_genomic | 0,004278481 | 0,124020875 | 0,773557592 | pt4 | 17-aug-2020 | AP | 00 | 00 | pt7 | 21-sep-2021 | NO | 00 | 00 | 17-aug-2020 | 21-sep-2021 | Unrelated | 7313 |
| 4 | ASM1421713v1_genomic | ASM2491733v1_genomic | 0,000498295 | 0,08597058 | 0,900912922 | pt4 | 17-aug-2020 | AP | 00 | 00 | pt8 | 4-sep-2022 | TX | 00 | 00 | 17-aug-2020 | 4-sep-2022 | Unrelated | 145 |
| 5 | ASM1421713v1_genomic | ASM2539267v1_genomic | 0,000156939 | 0,10040438 | 0,895510335 | pt4 | 17-aug-2020 | AP | 00 | 00 | pt9 | 23-sep-2022 | RA | 00 | 00 | 17-aug-2020 | 23-sep-2022 | Unrelated | 83 |
| 6 | ASM1421713v1_genomic | ASM972006v1_genomic | 0,000523388 | 0,08677614 | 0,899463797 | pt4 | 17-aug-2020 | AP | 00 | 00 | pt3 | 27-nov-2017 | US | 00 | 00 | 17-aug-2020 | 27-nov-2017 | Unrelated | 96 |
输入与预期
- 输入的query ID列表 =
[ASM1527755v1_genomic, ASM1930313v1_genomic, ASM194037v1_genomic, ASM2008964v1_genomic] - 预期输出:与主DataFrame结构一致的表格,但仅包含输入列表中一个元素在query列、另一个元素在reference列的记录。
问题原因与验证方案
核心原因
你的函数逻辑是筛选主DataFrame中query和reference同时属于目标列表的记录,但忽略了一个关键前提:主DataFrame本身可能不包含所有预期的成对组合。
比如示例数据中,目标列表里的ASM1527755v1_genomic只出现在reference列,从未作为query出现过,因此以它为query、其他目标元素为reference的记录根本不存在于主DataFrame中,自然无法被筛选出来。
验证步骤
- 检查目标列表中的元素是否都在主DataFrame的
query列出现过:
target_list = df_selection_ur["query"].unique().tolist() missing_in_query = [x for x in target_list if x not in df_metadata["query"].unique()] print("在query列缺失的元素:", missing_in_query)
- 统计主DataFrame中实际存在的目标元素成对组合数量,对比预期:
from itertools import combinations # 生成所有预期的无序成对组合 expected_pairs = set(combinations(target_list, 2)) # 提取主DataFrame中符合条件的无序成对组合 existing_pairs = set(df_metadata[ df_metadata["query"].isin(target_list) & df_metadata["reference"].isin(target_list) ].apply(lambda row: tuple(sorted((row["query"], row["reference"]))), axis=1)) # 找出缺失的组合 missing_pairs = expected_pairs - existing_pairs print("缺失的成对组合数量:", len(missing_pairs)) print("缺失的组合:", missing_pairs)
解决方案
根据验证结果,有两种处理方式:
- 补充数据:如果主DataFrame确实缺少部分成对记录,需要补充这些缺失的query-reference组合数据,才能得到完整的171组结果。
- 调整筛选逻辑:如果允许接受
(A,B)和(B,A)两种顺序的记录(只要两个元素都在目标列表中即可),可以保留原逻辑,或者改用更清晰的写法:
def metadata_def_epi(df_metadata, df_selection_ur): target_list = df_selection_ur["query"].unique().tolist() # 筛选query和reference都属于目标列表的所有记录 mask = df_metadata["query"].isin(target_list) & df_metadata["reference"].isin(target_list) df_out = df_metadata[mask] return df_out
内容的提问来源于stack exchange,提问作者Freek de Kreek
相关产品推荐
相关产品推荐

