Normalizer与Standardizer两种缩放方法对比及运行报错问题咨询
报错原因分析
- 直接触发
NameError的原因:你在Standardizer的__init__方法中调用类内方法x_avg_std时,没有添加实例前缀self。Python调用类内实例方法必须通过实例(即self)或类本身访问,直接写函数名的话会在全局作用域查找该函数,找不到就会抛出未定义的报错。如果你写的Normalizer类可以正常运行,大概率是你当前运行环境的全局作用域中刚好定义过同名的x_min_max全局函数,否则Normalizer也会抛出完全一样的NameError。 - 隐藏的代码错误:两个类的内部方法定义都不符合Python实例方法的规范,实例方法的第一个参数必须是实例自身(通常命名为
self),你当前写的x_min_max、x_avg_std都缺失了self参数,哪怕你给调用加上self.前缀,也会因为参数数量不匹配抛出新的报错。另外Normalizer的normalize_data方法里还存在参数取值颠倒的bug,你从params里取第0位当最大值、第1位当最小值,但x_min_max返回的是(最小值, 最大值),会导致归一化结果完全错误。
关于__init__调用后置类方法的疑问
不存在“不建议在__init__中调用定义在后方的类方法”的说法。Python在实例化类的时候,会先完成整个类所有属性、方法的加载,再执行__init__方法,类内方法的定义顺序完全不影响调用,只要你通过self.正确访问即可。
修复后可正常运行的代码
class Normalizer(): def __init__(self, dataframe): self.params = [] for col in dataframe.columns: self.params.append(self.x_min_max(dataframe[col])) def x_min_max(self, data): minimum = min(data) maximum = max(data) return minimum, maximum def normalize_data(self, x): normalized = [] for i, val in enumerate(x): x_min = self.params[i][0] x_max = self.params[i][1] normalized.append((x[i]-x_min)/(x_max-x_min)) return normalized class Standardizer(): def __init__(self, dataframe): self.params = [] for col in dataframe.columns: self.params.append(self.x_avg_std(dataframe[col])) def x_avg_std(self, data): avg = sum(data) / len(data) std = (sum([((x - avg) ** 2) for x in data]) / (len(data) - 1)) ** 0.5 return avg, std def standardize_data(self, x): standardized = [] for i, val in enumerate(x): x_avg = self.params[i][0] x_std = self.params[i][1] standardized.append((x[i] - x_avg)/x_std) return standardized
内容的提问来源于stack exchange,提问作者yuan
相关产品推荐
相关产品推荐

