如何在Pandas中创建函数并逐行应用?分组处理医疗记录找首诊地点
嘿,这两个Pandas问题我都熟,来给你一步步讲清楚!
问题1:如何在Pandas中创建函数并对DataFrame的每一行应用该函数?
其实操作起来很直观,核心就是用apply()方法,分两步走就行:
第一步:定义你的自定义函数
函数的参数会接收DataFrame的每一行数据,你可以通过row['列名']来获取行内的具体值。比如我想给每行的两列算个总和,函数可以这么写:def get_row_total(row): return row['col_a'] + row['col_b']第二步:用apply()将函数应用到每一行
记得一定要设置axis=1(axis=0是按列处理,axis=1才是按行),还可以直接把结果生成新列:import pandas as pd # 先整个示例DataFrame df = pd.DataFrame({'col_a': [10, 20, 30], 'col_b': [5, 15, 25]}) # 应用函数,生成新列total df['total'] = df.apply(get_row_total, axis=1)
要是你的函数逻辑比较简单,也可以用lambda表达式省点代码,比如上面的例子可以写成:
df['total'] = df.apply(lambda row: row['col_a'] + row['col_b'], axis=1)
小贴士:如果你的逻辑能改成矢量化操作(比如用Pandas内置的列运算),性能会比逐行apply好很多,但复杂逻辑的话,apply还是最直接的选择。
问题2:按ID分组后识别患者出院后的首个就诊地点
这个需求确实有点细节要抠,我结合你提到的规则,再补充常见的场景情况,给你一套可行的方案:
首先假设你的DataFrame df 包含这些关键列:ID(患者ID)、begin_date(就诊/住院开始日期)、end_date(就诊/住院结束日期)、location(就诊地点)。
完整处理步骤:
先给数据排好序
必须确保每个患者的记录是按时间顺序排列的,不然后续判断会乱:# 按ID分组,再按begin_date升序排序,然后重置索引 df = df.sort_values(by=['ID', 'begin_date']).reset_index(drop=True)写自定义函数处理每个患者的分组
按照你提到的规则,再补充两种常见情况,函数逻辑如下:def find_first_post_discharge(group): # 取该患者首次记录的出院日期(如果是首次住院,你可以加筛选条件,比如筛选record_type为住院的行) first_discharge_date = group.iloc[0]['end_date'] # 情况1:找begin_date正好等于出院日期的就诊记录 matched_records = group[group['begin_date'] == first_discharge_date] if not matched_records.empty: # 排序后第一个就是对应地点 return matched_records.iloc[0]['location'] # 情况2:没有完全匹配的,找出院日期之后最早的就诊记录 post_discharge_records = group[group['begin_date'] > first_discharge_date] if not post_discharge_records.empty: return post_discharge_records.iloc[0]['location'] # 情况3:如果出院后没有任何就诊记录,返回空值或者你指定的标识 return None将函数应用到每个分组
用groupby()结合apply(),可以得到每个患者对应的首个就诊地点,还能合并回原DataFrame:# 得到每个ID的首个出院后就诊地点 first_locations = df.groupby('ID').apply(find_first_post_discharge).reset_index(name='first_post_discharge_location') # 合并回原DataFrame,方便查看 df = df.merge(first_locations, on='ID', how='left')
重要提醒:
- 一定要把日期列转换成
datetime类型,不然日期比较会出错:df['begin_date'] = pd.to_datetime(df['begin_date']) df['end_date'] = pd.to_datetime(df['end_date']) - 如果你的“首次出院”不是分组的首行,而是特定类型的记录(比如住院记录),可以修改
first_discharge_date的获取逻辑,比如:# 筛选出该患者的住院记录,取最早的出院日期 inpatient_records = group[group['record_type'] == 'inpatient'] if not inpatient_records.empty: first_discharge_date = inpatient_records.iloc[0]['end_date'] else: # 没有住院记录的情况,返回空或者其他处理 return None
内容的提问来源于stack exchange,提问作者CandleWax
相关产品推荐
相关产品推荐

