Pandas列范围值取平均替换报错,求正确实现方案
问题解决:处理Pandas DataFrame中的范围值并计算平均值
错误原因
你的代码报错是因为目标列是混合类型(包含float数值、字符串范围、NaN),使用str.contains和str.split这类字符串方法时,非字符串元素(比如float类型的0.647、0,以及NaN)会返回NaN。当你对这些NaN应用lambda函数时,会触发TypeError: 'float' object is not iterable——因为NaN是float类型,无法被迭代拆分。
解决方案
我们需要先统一列的类型,再针对性处理范围值、数值和NaN。以下提供两种可行方法:
方法1:自定义函数+apply(直观易读)
先定义一个处理单个值的函数,再用apply遍历整列:
import pandas as pd import numpy as np # 可复现数据 df = pd.DataFrame([0.647,0.88,0,0.73,'1.7 - 2.1','1.2 - 1.5',2.5 ,np.NaN,'1.5 - 1.9','1.3 - 1.5',0.4,'1.7 - 2.9'],columns=['Average Weight (Kg)']) def process_weight(val): # 先处理NaN if pd.isna(val): return np.nan # 统一转为字符串,避免类型混乱 val_str = str(val).strip() # 判断是否为范围值 if '-' in val_str: # 拆分、去空格、转浮点后计算平均值 nums = [float(x.strip()) for x in val_str.split('-')] return np.mean(nums) else: # 非范围值转为浮点,处理异常情况 try: return float(val_str) except: return np.nan # 应用函数到目标列 df['Average Weight (Kg)'] = df['Average Weight (Kg)'].apply(process_weight)
方法2:矢量化操作(高效适合大数据集)
利用Pandas的矢量化方法替代apply,提升处理速度:
import pandas as pd import numpy as np # 可复现数据 df = pd.DataFrame([0.647,0.88,0,0.73,'1.7 - 2.1','1.2 - 1.5',2.5 ,np.NaN,'1.5 - 1.9','1.3 - 1.5',0.4,'1.7 - 2.9'],columns=['Average Weight (Kg)']) # 统一转为字符串,处理NaN weight_str = df['Average Weight (Kg)'].astype(str) # 标记哪些行是范围值 is_range = weight_str.str.contains('-') # 处理范围值:拆分后转浮点,计算行平均值 range_results = weight_str[is_range].str.split('-', expand=True).apply(lambda x: x.str.strip()).astype(float).mean(axis=1) # 处理非范围值:转为数值,无法转换的(比如'NaN')设为NaN non_range_results = pd.to_numeric(weight_str[~is_range], errors='coerce') # 合并结果并重新对齐索引 df['Average Weight (Kg)'] = pd.concat([range_results, non_range_results]).reindex(df.index)
两种方法处理后,目标列的结果一致:范围值被替换为平均值,原数值、0和NaN均保留正确格式。
内容的提问来源于stack exchange,提问作者alex3465
相关产品推荐
相关产品推荐

