Python:如何根据同一DataFrame中另一列的值批量替换指定列内容
Python:如何根据同一DataFrame中另一列的值批量替换指定列内容
嘿,我完全懂你的需求啦——你希望每个患者(对应同一个caseid)的所有行里,把原本仅在某一行标记为1的那列(earlier_count/later_count/on_time_count),全部替换成该患者的caseid,其他列保持0对吧?咱们来一步步解决这个问题,先说说你之前尝试的代码为啥没成功,再给你高效的解决方案。
先分析你原代码的问题
你写的这段代码:
merged_2['earlier_count'].apply(lambda x: x if x == '0' else merged_2.loc[merged_2['caseid'] == x, 'caseid'].values[0])
逻辑上有个小问题:这里的x是earlier_count列里的0或1,当x=1时,你是在找caseid等于1的行,而不是当前行对应的那个患者的caseid,当然找不到正确的值啦。
高效解决方案
我们可以分两步走:先找出每个caseid对应的是哪一列有1,再批量给对应的列填充caseid。
步骤1:建立caseid与目标列的映射
首先,我们把数据“融化”一下,找出每个caseid对应的那个标记为1的列:
import pandas as pd # 把三个计数列转成键值对,筛选出值为1的行 caseid_col_mapping = merged_2.melt( id_vars='caseid', value_vars=['earlier_count', 'later_count', 'on_time_count'] ) # 只保留值为1的行,建立caseid到对应列的映射 caseid_col_mapping = caseid_col_mapping[caseid_col_mapping['value'] == 1].set_index('caseid')['variable'] # (可选)如果存在同一caseid对应多个1的情况,取第一个匹配的列 caseid_col_mapping = caseid_col_mapping.groupby(level=0).first()
步骤2:批量替换列内容
接下来,我们先把三个计数列重置为0,再根据刚才的映射,给每个caseid对应的列填充caseid值:
# 先把三个计数列全部设为0 merged_2[['earlier_count', 'later_count', 'on_time_count']] = 0 # 遍历每个caseid和对应的目标列,填充值 for caseid, target_col in caseid_col_mapping.items(): merged_2.loc[merged_2['caseid'] == caseid, target_col] = caseid
举个测试例子验证效果
假设你有这样的测试数据:
data = { 'caseid': [361474, 361474, 361474, 123456, 123456], 'earlier_count': [1, 0, 0, 0, 0], 'later_count': [0, 0, 0, 1, 0], 'on_time_count': [0, 0, 0, 0, 0] } merged_2 = pd.DataFrame(data)
运行上面的代码后,结果会变成:
| caseid | earlier_count | later_count | on_time_count |
|---|---|---|---|
| 361474 | 361474 | 0 | 0 |
| 361474 | 361474 | 0 | 0 |
| 361474 | 361474 | 0 | 0 |
| 123456 | 0 | 123456 | 0 |
| 123456 | 0 | 123456 | 0 |
完全符合你想要的效果!
备注:内容来源于stack exchange,提问作者Sapir Bar
相关产品推荐
相关产品推荐

