归一化函数隐藏测试用例未通过,寻求问题排查帮助
问题描述
我在完成课程作业时需要实现一个归一化函数,要求如下:
- 接收三个参数:数据文件路径、待归一化属性(列名,对应
Open/High/Low/Close/Volume之一)、归一化类型(min_max或z_score) - 根据指定类型应用对应归一化公式,返回以原始数值为键、归一化值为值的字典
该函数在样本数据集./data/HistoricalQuotes.csv测试正常,但提交后隐藏测试用例未通过,无法定位问题,附上我的实现代码:
def normalization (fname, attr, normType): ''' Input Parameters: fname: Name of the csv file contiaining historical quotes attr: The attribute to be normalized normType: The type of normalization Output: a dictionary where each key is the original column value and each value is the normalised column value. ''' result = {} df = pd.read_csv(fname) select_column = df[attr] if normType == 'min_max': for x in select_column: result[x] = round((((x - min(select_column))/(max(select_column) - min(select_column))) * (1-0) + 0), 1) elif normType == 'z_score': for x in select_column: result[x] = round((x - np.mean(select_column))/ np.std(select_column), 1) return result
问题分析与修复方案
以下是可能导致隐藏用例失败的问题点及对应的修复代码:
1. 重复原始值覆盖问题
字典的键具有唯一性,若原始数据中存在重复的数值,后续遍历到的归一化值会覆盖之前的,导致结果缺失部分条目,这是隐藏用例失败的常见原因。
2. 重复计算统计量
循环内反复调用min()/max()/np.mean()/np.std()会重复遍历列数据,不仅效率低下,还可能因浮点数精度问题导致计算偏差。
3. 标准差类型不匹配
np.std()默认使用总体标准差(ddof=0),而多数统计场景(包括课程作业)通常要求使用样本标准差(ddof=1),这会导致z-score计算结果偏差。
4. 边界情况未处理
当列内所有数值相同时,min-max归一化的分母为0、z-score的标准差为0,会引发计算错误或NaN值。
5. 空值未处理
若数据中存在NaN值,当前代码会直接参与计算,导致归一化结果异常。
修复后的代码
import pandas as pd import numpy as np def normalization(fname, attr, normType): ''' Input Parameters: fname: Name of the csv file containing historical quotes attr: The attribute to be normalized normType: The type of normalization Output: a dictionary where each key is the original column value and each value is the normalised column value. For duplicate original values, values are stored as a list to preserve all normalized results ''' df = pd.read_csv(fname) # 先移除空值,若作业要求填充空值可替换为fillna() select_column = df[attr].dropna() # 提前计算所有需要的统计量,避免重复遍历 if normType == 'min_max': col_min = select_column.min() col_max = select_column.max() # 处理所有值相同的边界情况 if col_max == col_min: normalized_vals = [0.0] * len(select_column) else: normalized_vals = ((select_column - col_min) / (col_max - col_min)).tolist() elif normType == 'z_score': col_mean = select_column.mean() # 使用样本标准差(ddof=1),若要求总体标准差可改为ddof=0 col_std = select_column.std(ddof=1) # 处理标准差为0的边界情况 if col_std == 0: normalized_vals = [0.0] * len(select_column) else: normalized_vals = ((select_column - col_mean) / col_std).tolist() else: raise ValueError("normType must be 'min_max' or 'z_score'") result = {} # 遍历原始值和归一化值,处理重复键 for orig_val, norm_val in zip(select_column.tolist(), normalized_vals): # 可根据作业要求调整保留的小数位数 rounded_norm = round(norm_val, 4) if orig_val in result: # 若原始值重复,将归一化值存入列表 if isinstance(result[orig_val], list): result[orig_val].append(rounded_norm) else: result[orig_val] = [result[orig_val], rounded_norm] else: result[orig_val] = rounded_norm return result
修复说明
- 提前计算统计量,提升效率并避免精度偏差
- 处理重复原始值,用列表保存所有对应的归一化结果,防止覆盖
- 适配样本标准差,符合常规统计需求
- 处理数值全相同、空值等边界情况
- 调整小数保留位数,减少因精度丢失导致的测试失败
内容的提问来源于stack exchange,提问作者Scarlett Valentin
相关产品推荐
相关产品推荐

