如何基于多列多条件为Pandas DataFrame生成指定新列?
多条件生成DataFrame新列的实现方式
原始DataFrame
c1 c2 0 0 "phrase_x 12" 1 0 "phrase_y 34" 2 1 "phrase_x 56" 3 1 "phrase_y 78"
需求规则
- 当
c1 == 0且c2包含phrase_x时,c3填充c2按空格分割后的数字部分 - 当
c1 == 0且c2包含phrase_y时,c4填充c2按空格分割后的数字部分 - 当
c1 == 1且c2包含phrase_x时,c5填充c2按空格分割后的数字部分 - 当
c1 == 1且c2包含phrase_y时,c6填充c2按空格分割后的数字部分 - 未满足条件的单元格用
NaN填充
期望结果
c1 c2 c3 c4 c5 c6 0 0 "phrase_x 12" 12 NaN NaN NaN 1 0 "phrase_y 34" NaN 34 NaN NaN 2 1 "phrase_x 56" NaN NaN 56 NaN 3 1 "phrase_y 78" NaN NaN NaN 78
尝试过的方法
用户尝试过单条件loc语句,但无法满足多条件需求:
df.loc[df['c2'].str.contains("phrase_x") , 'c3'] = df['c2'].str.split('-> ').str[1] df.loc[df['c2'].str.contains("phrase_y") , 'c4'] = df['c2'].str.split('-> ').str[1]
使用np.where时触发错误:
ValueError: Cannot set a DataFrame with multiple columns to the single column Budget Outlet 1
解决方案
方法一:用loc实现多条件赋值
提前提取c2中的数字部分,减少重复计算,再通过多条件组合完成赋值:
import pandas as pd import numpy as np # 构造原始数据 data = {'c1': [0,0,1,1], 'c2': ['phrase_x 12', 'phrase_y 34', 'phrase_x 56', 'phrase_y 78']} df = pd.DataFrame(data) # 提取c2中的数字部分,转成数值类型 df['num'] = df['c2'].str.split().str[1].astype(float) # 初始化c3-c6列为NaN df[['c3','c4','c5','c6']] = np.nan # 多条件赋值,注意用&连接条件,每个条件加括号避免优先级问题 df.loc[(df['c1'] == 0) & (df['c2'].str.contains('phrase_x')), 'c3'] = df['num'] df.loc[(df['c1'] == 0) & (df['c2'].str.contains('phrase_y')), 'c4'] = df['num'] df.loc[(df['c1'] == 1) & (df['c2'].str.contains('phrase_x')), 'c5'] = df['num'] df.loc[(df['c1'] == 1) & (df['c2'].str.contains('phrase_y')), 'c6'] = df['num'] # 可选:删除临时的num列 df = df.drop('num', axis=1)
方法二:更优的重塑方式(适合规则扩展)
如果后续条件可能增加,通过拆分特征+数据重塑的方式更灵活,无需编写大量loc语句:
import pandas as pd # 构造原始数据 data = {'c1': [0,0,1,1], 'c2': ['phrase_x 12', 'phrase_y 34', 'phrase_x 56', 'phrase_y 78']} df = pd.DataFrame(data) # 拆分c2为phrase和num两列 df[['phrase', 'num']] = df['c2'].str.split(expand=True) df['num'] = df['num'].astype(float) # 根据c1和phrase生成对应的目标列名 df['col_name'] = df.apply( lambda row: f"c{3 if row['c1'] == 0 else 5}{'' if row['phrase'] == 'phrase_x' else 1}", axis=1 ) # 重塑数据为宽表,合并回原数据 pivot_df = df.pivot(index=df.index, columns='col_name', values='num') # 调整列名匹配需求 pivot_df = pivot_df.rename(columns={'c3':'c3', 'c31':'c4', 'c5':'c5', 'c51':'c6'}) result = df[['c1','c2']].join(pivot_df) print(result)
内容的提问来源于stack exchange,提问作者MrTomatosoup
相关产品推荐
相关产品推荐

