使用np.select处理Pandas混合类型列分箱映射的报错解决
DataFrame混合类型列分箱映射报错解决
问题场景
需要将包含数字字符串与文本的DataFrame列映射为4个分类,示例数据:
df['data_column'] = ['22', '8', '11', 'Text', '17', 'Text', '6']
映射规则:
- 1 至 10: superb
- 10 至 20: awesome
- 20 至 30: great
- 'Text': text
尝试以下代码后触发错误:ValueError: shape mismatch: objects cannot be broadcast to a single shape.
my_criteria = [df['data_column'][df['data_column'] != 'Text'].astype('int64').between(1, 10), df['data_column'][df['data_column'] != 'Text'].astype('int64').between(10, 20), df['data_column'][df['data_column'] != 'Text'].astype('int64').between(20, 30), df['data_column'][df['data_column'] == 'Text']] my_values = ['superb', 'awesome', 'great', 'text'] df['data_column'] = np.select(my_criteria, my_values, 0)
期望输出:
df['data_column'] = ['great', 'superb', 'awesome', 'text', 'awesome', 'text', 'superb']
错误原因
前三个条件通过df['data_column'] != 'Text'筛选后,得到的布尔数组长度为5(原列共7条数据,去掉2条Text),但第四个条件的布尔数组长度为7,np.select要求所有条件数组的形状完全一致,因此触发形状不匹配错误。
解决方法
方法一:统一条件数组长度(高效)
先将混合类型列转为数值类型,把Text转为NaN,再基于原长度的数组定义条件:
import pandas as pd import numpy as np df = pd.DataFrame({'data_column': ['22', '8', '11', 'Text', '17', 'Text', '6']}) # 将列转为数值,Text自动转为NaN num_col = pd.to_numeric(df['data_column'], errors='coerce') # 所有条件均为原DataFrame长度的布尔数组 my_criteria = [ num_col.between(1, 10), num_col.between(10, 20), num_col.between(20, 30), df['data_column'] == 'Text' ] my_values = ['superb', 'awesome', 'great', 'text'] # 执行映射 df['data_column'] = np.select(my_criteria, my_values, default=0)
方法二:逐行处理(直观)
用apply遍历每一行,直接按规则判断:
import pandas as pd df = pd.DataFrame({'data_column': ['22', '8', '11', 'Text', '17', 'Text', '6']}) def map_category(x): if x == 'Text': return 'text' num = int(x) if 1 <= num <= 10: return 'superb' elif 10 < num <= 20: return 'awesome' elif 20 < num <= 30: return 'great' return 0 df['data_column'] = df['data_column'].apply(map_category)
说明
- 方法一适合大数据量,利用pandas向量化操作,执行效率更高;
- 方法二逻辑更直观,适合小数据量或规则复杂的场景。
内容的提问来源于stack exchange,提问作者Supernova
相关产品推荐
相关产品推荐

