Pandas列规范化报错:'float' object has no attribute 'max' 排查与修复
问题分析与解决方案
你遇到的问题核心在于**apply方法的执行逻辑**:当你对df['score1']调用apply(normalize)时,normalize函数里的x是列中的单个元素(比如-1、0、2这类整数/浮点数),而单个数值类型是没有max()方法的——max()是Pandas Series或NumPy数组的专属方法,这就是为什么你会收到AttributeError: 'int' object has no attribute 'max'的原因。
硬编码最大值虽然能临时运行,但显然不够灵活,下面给你两种更优雅的修复方案:
方案一:使用矢量化操作(推荐)
Pandas的强项是矢量化运算,比逐元素的apply效率更高,代码也更简洁。我们可以先把-1替换为NaN,再用列的有效最大值(排除-1后的最大值)进行归一化:
import numpy as np import pandas as pd df = pd.DataFrame({'key' : [111, 222, 333, 444, 555, 666, 777, 888, 999], 'score1' : [-1, 0, 2, -1, 7, 0, 15, 0, 1], 'score2' : [2, 2, -1, 10, 0, 5, -1, 1, 0]}) # 处理score1列 max_score1 = df['score1'][df['score1'] != -1].max() df['norm1'] = df['score1'].replace(-1, np.nan) / max_score1 # 处理score2列 max_score2 = df['score2'][df['score2'] != -1].max() df['norm2'] = df['score2'].replace(-1, np.nan) / max_score2 print(df)
输出结果:
key score1 score2 norm1 norm2 0 111 -1 2 NaN 0.200000 1 222 0 2 0.000000 0.200000 2 333 2 -1 0.133333 NaN 3 444 -1 10 NaN 1.000000 4 555 7 0 0.466667 0.000000 5 666 0 5 0.000000 0.500000 6 777 15 -1 1.000000 NaN 7 888 0 1 0.000000 0.100000 8 999 1 0 0.066667 0.000000
如果想更简洁,也可以用mask方法直接标记-1为缺失值:
df['norm1'] = df['score1'].mask(df['score1'] == -1, np.nan) / df['score1'].mask(df['score1'] == -1).max()
方案二:修改apply的调用方式(传参)
如果坚持要用自定义函数+apply,可以先计算列的有效最大值,再通过apply的args参数把最大值传给函数:
def normalize(x, max_val): if x == -1: return np.nan else: return x / max_val # 计算score1的有效最大值(排除-1) max_score1 = df['score1'][df['score1'] != -1].max() df['norm1'] = df['score1'].apply(normalize, args=(max_score1,)) # score2同理 max_score2 = df['score2'][df['score2'] != -1].max() df['norm2'] = df['score2'].apply(normalize, args=(max_score2,))
这样函数就能拿到整个列的最大值,完美避免了硬编码的问题。
内容的提问来源于stack exchange,提问作者glpsx
相关产品推荐
相关产品推荐

