astype()不改变原数组内存,因返回新数组且未赋值;必须arr = arr.astype(dtype)才生效,且需检查arr.dtype和arr.nbytes确认。

为什么 astype() 改类型后内存没变小?
常见错觉:调用 arr.astype(np.float32) 后 arr.nbytes 没降 —— 因为没赋值回去。astype() 默认返回新数组,原数组不变。
- 必须显式赋值:
arr = arr.astype(np.float32) - 原地转换不可行(
astype()不支持copy=False保证安全),除非你确认数据可安全截断且用arr.view()或arr.dtype =(极少数场景,风险高) - 检查是否真改成功:
arr.dtype和arr.nbytes都要再看一遍
float32 和 int64 哪个更省内存?看原始类型再决定
从 float64 → float32:内存减半;从 int64 → int32:也减半;但 int64 本身比 float32 占更多字节(8 vs 4),所以“改成 int64”通常不省内存,反而是浪费。
- 原始是
float64?优先转np.float32 - 原始是
int64但数值范围 ≤ ±2147483647?可安全转np.int32(省一半) - 原始是
object或字符串?astype()会报TypeError: data type 'float32' not understood,得先用pd.to_numeric()或astype(str).astype(float)清洗 - 注意精度损失:
float32有效位数约7位,科学计数大数或微小差值可能出错
批量改 dtype 的坑:DataFrame 列类型不统一怎么办
对 pandas.DataFrame 直接 df.astype(np.float32) 会失败,如果某列含 NaN 且是整型(int64 列不能存 NaN),pandas 会自动升成 float64 再转,绕过你的意图。
- 逐列处理更稳:
df['col'] = df['col'].astype(np.float32) - 整表转换前,先过滤掉非数值列:
df.select_dtypes(include='number').astype(np.float32) - 含
NaN的整型列,要么填零/插值后再转int32,要么接受它变成float32(这是最常见、最安全的路径) - 别信
df.memory_usage(deep=True).sum()的初始值——它可能缓存旧 dtype,改完立刻重算
astype() 性能不总快:小数组别硬转,大数组注意副本开销
astype() 必然创建新数组,意味着全量内存拷贝。对几 GB 的数组,这步本身耗时且瞬时内存翻倍(旧+新同时存在)。
- 小数组(
- 大数组:考虑
np.memmap或分块处理,避免一次性加载+转换 - 想原地改?
arr[:] = arr.astype(np.float32)看似省内存,实则仍需临时空间,且可能因精度截断导致静默错误 - 某些场景下,用
np.float32(arr)比arr.astype(np.float32)略快(底层调用更直接),但行为一致,不必强求
dtype 转换不是无损开关,float32 的精度边界、int 类型对 NaN 的排斥、DataFrame 中隐式类型提升,这些才是实际压内存时真正卡住的地方。

















