You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用apply筛选DataFrame相似行返回异常结果,寻求解决方案

问题描述

我的数据集包含UNITID、institution_name、program_name、CIPCODE、type列,示例数据如下:

UNITID : 100654
institution_name : Harvard
program_name : Medicine
CIPCODE : 52.0203
type : Bachelor's

需求:针对原数据集中特定UNITID对应的子集data_subset,筛选满足以下条件的相似行:

  • CIPCODE前四位数字相同
  • CIPCODE剩余数字不同
  • type字段相同
  • UNITID字段不同

我编写的代码执行后,得到的是包含多个DataFrame(含空DataFrame)的序列,而非预期的单一筛选结果:

# data是原始DataFrame

data['CIPCODE'] = data['CIPCODE'].astype(str).str.zfill(7)
data['CIPCODE_group'] = data['CIPCODE'].str.replace(".", "").str[:4]
data['CIPCODE_decimal'] = data['CIPCODE'].str.replace(".", "").str[4:]

def find_similar_programs(row: pd.Series, df: pd.DataFrame):
  
    return df[
        (df['CIPCODE_group'] == row['CIPCODE_group'])
        & (df['CIPCODE_decimal'] != row['CIPCODE_decimal'])
        & (df['type'] == row['type'])
        & (df['UNITID'] != row['UNITID'])]

data_subset=data[data['UNITID']==166027]

similar_programs = data_subset.apply(find_similar_programs, df = data, axis = 1)
解决方案

问题原因

apply会对data_subset的每一行单独执行筛选逻辑,返回对应行的匹配结果DataFrame,最终得到的是一个存储多个DataFrame的Series,而非合并后的单一结果集。

方法一:批量筛选(推荐,效率更高)

直接提取data_subset的关键条件,一次性完成筛选,避免逐行遍历:

import pandas as pd

# 保留原始CIPCODE处理逻辑
data['CIPCODE'] = data['CIPCODE'].astype(str).str.zfill(7)
data['CIPCODE_group'] = data['CIPCODE'].str.replace(".", "").str[:4]
data['CIPCODE_decimal'] = data['CIPCODE'].str.replace(".", "").str[4:]

# 目标子集
target_unitid = 166027
data_subset = data[data['UNITID'] == target_unitid]

# 提取子集的关键匹配条件
# 要匹配的CIPCODE分组和type组合
group_type_pairs = data_subset[['CIPCODE_group', 'type']].drop_duplicates()
# 子集里的CIPCODE后缀(需要排除)
exclude_decimals = data_subset['CIPCODE_decimal'].unique()

# 合并条件筛选相似行
similar_programs = data.merge(group_type_pairs, on=['CIPCODE_group', 'type'], how='inner')
similar_programs = similar_programs[
    (~similar_programs['CIPCODE_decimal'].isin(exclude_decimals))
    & (similar_programs['UNITID'] != target_unitid)
].reset_index(drop=True)

方法二:合并现有结果

如果要保留原有的逐行筛选逻辑,只需将返回的多个DataFrame合并并去重:

# 保留你原有的代码逻辑
data['CIPCODE'] = data['CIPCODE'].astype(str).str.zfill(7)
data['CIPCODE_group'] = data['CIPCODE'].str.replace(".", "").str[:4]
data['CIPCODE_decimal'] = data['CIPCODE'].str.replace(".", "").str[4:]

def find_similar_programs(row: pd.Series, df: pd.DataFrame):
    return df[
        (df['CIPCODE_group'] == row['CIPCODE_group'])
        & (df['CIPCODE_decimal'] != row['CIPCODE_decimal'])
        & (df['type'] == row['type'])
        & (df['UNITID'] != row['UNITID'])]

data_subset = data[data['UNITID'] == 166027]
similar_programs_series = data_subset.apply(find_similar_programs, df=data, axis=1)

# 合并所有非空DataFrame并去重
similar_programs = pd.concat(
    [df for df in similar_programs_series if not df.empty],
    ignore_index=True
).drop_duplicates().reset_index(drop=True)

内容的提问来源于stack exchange,提问作者analyst92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 16:15:10