标准化DataFrame时的自动类型转换问题及解决方法
解决Pandas标准化后Year列类型未转为浮点的问题
我来帮你分析下这个问题,顺便给你几个靠谱的解决办法:
问题核心原因
你遇到的关键问题是Pandas的at方法会严格遵循原列的数据类型。你的Year列一开始是整数类型(int),哪怕你计算出了浮点数结果,用at赋值回去的时候,Pandas会自动把浮点数强制转换为整数(直接截断小数部分),所以你看到的结果还是整数,而非预期的浮点型。
举个实际的例子:如果计算出来的标准化值是-1.3,因为原列是int类型,at会直接把它转成-1,也就出现了你输出里的整数结果。
可行解决方案
给你三种方案,优先推荐第二种,最贴合Pandas的最佳实践:
1. 先转换列类型再执行标准化
在循环操作前,先把Year列转换成浮点型,确保赋值时能保留小数:
import pandas as pd import numpy as np male100 = pd.read_csv('data/male100.csv', header = 0) # 先将Year列转为浮点型 male100['Year'] = male100['Year'].astype(float) # 再执行原有标准化逻辑 time_mean = male100['Time'].mean() time_std = male100['Time'].std() year_mean = male100['Year'].mean() year_std = male100['Year'].std() elem_nb = male100.shape[0] for i in range(elem_nb): male100.at[i, 'Year'] = male100.at[i, 'Year'] - year_mean male100.at[i, 'Year'] = male100.at[i, 'Year'] / year_std print(male100)
2. 用向量化操作替代循环(强烈推荐)
Pandas最擅长向量化运算,不仅代码简洁,运行效率比循环高得多,还能自动处理类型转换:
import pandas as pd import numpy as np male100 = pd.read_csv('data/male100.csv', header = 0) # 直接对整列执行标准化,一步到位 male100['Year'] = (male100['Year'] - male100['Year'].mean()) / male100['Year'].std() # Time列的标准化也可以用同样的方式 male100['Time'] = (male100['Time'] - male100['Time'].mean()) / male100['Time'].std() print(male100)
这种方式下,运算结果是浮点数,Pandas会自动将Year列的类型调整为float64,完全不需要手动处理类型问题。
3. 改用loc赋值(不推荐,但可行)
如果你一定要保留循环逻辑,可以把at换成loc,配合提前转换列类型:
male100['Year'] = male100['Year'].astype(float) for i in range(elem_nb): male100.loc[i, 'Year'] = (male100.loc[i, 'Year'] - year_mean) / year_std
验证效果
执行修改后的代码后,你可以用print(male100.dtypes)查看列类型,会发现Year列已经变成float64,输出结果也会显示完整的小数部分。
内容的提问来源于stack exchange,提问作者Pierre P.




