基于另一列值创建新列:修复Pandas三种方法的实现问题
嗨,我来帮你搞定这个Pandas列映射的问题!你遇到的报错都是很典型的操作误区,下面我会逐个给出三种方法的正确实现,再聊聊效率最高的最优方案。
首先先准备一个示例DataFrame方便演示:
import pandas as pd import numpy as np df = pd.DataFrame({ 'status': ['F-On', 'S-On', 'circ', 'TH', 'circInS', 'R', 'S', 'unknown'] })
1. 使用.loc的正确实现
你之前遇到的「Series真值歧义」,大概率是直接用df['status'] == 'F-On' | df['status'] == 'S-On'这种写法——|的优先级比==高,没加括号会导致逻辑混乱。用.isin()可以完美解决这个问题,同时简化代码:
# 初始化新列,先默认保留原值 df['grouped_status'] = df['status'] # 映射(F-On, S-On)到'On' df.loc[df['status'].isin(['F-On', 'S-On']), 'grouped_status'] = 'On' # 映射(circ, TH, circInS)到'fooON' df.loc[df['status'].isin(['circ', 'TH', 'circInS']), 'grouped_status'] = 'fooON'
2. 使用np.where的正确实现
np.where多条件组合时,每个独立条件都必须加括号,否则会触发真值歧义报错。这里用嵌套np.where来实现多规则判断:
df['grouped_status'] = np.where( df['status'].isin(['F-On', 'S-On']), 'On', np.where( df['status'].isin(['circ', 'TH', 'circInS']), 'fooON', df['status'] # 不满足条件的直接保留原值 ) )
3. 使用df.apply的正确实现
你说apply输出半为空,应该是自定义函数没有覆盖所有情况,导致部分值返回了None。写一个明确覆盖所有规则的函数就没问题了:
def map_status(status): if status in ['F-On', 'S-On']: return 'On' elif status in ['circ', 'TH', 'circInS']: return 'fooON' else: return status # R、S及其他值直接返回原值 df['grouped_status'] = df['status'].apply(map_status)
最优行操作方案
上面三种方法都能实现需求,但如果你的数据量较大(比如百万级以上),**pd.Series.replace()**是效率最高的选择——它是完全向量化的操作,不需要逐行循环,代码也最简洁:
先定义映射字典,然后直接调用replace:
status_map = { 'F-On': 'On', 'S-On': 'On', 'circ': 'fooON', 'TH': 'fooON', 'circInS': 'fooON' } df['grouped_status'] = df['status'].replace(status_map)
这个方法会自动保留不在字典里的原值(比如R、S),完全符合你的需求。
最终示例DataFrame的输出结果如下:
| status | grouped_status |
|---|---|
| F-On | On |
| S-On | On |
| circ | fooON |
| TH | fooON |
| circInS | fooON |
| R | R |
| S | S |
| unknown | unknown |
内容的提问来源于stack exchange,提问作者user6647375
相关产品推荐
相关产品推荐

