使用astype('|S')优化Pandas内存后,to_csv输出带b前缀问题
解决Pandas导出CSV时字节类型列出现
b'...'的问题 我刚踩过类似的坑,来给你捋清楚怎么搞定这个问题~
问题根源
你用astype('|S')把字符串列转成了字节数组(bytes)类型,这确实能大幅压缩内存(毕竟object类型存的是字符串对象的指针,字节数组是连续紧凑的内存块),但Pandas导出CSV时,会直接输出bytes对象的Python原生表示形式——也就是带b'...'前缀的格式,这就导致了导出内容异常。
三种可行解决方案
1. 导出前把字节列转回字符串
如果已经完成了所有数据处理步骤,在导出前把这些字节列解码回字符串就行,代码示例:
# 遍历所有列,对字节类型列执行UTF-8解码 for col in data_frame.columns: if data_frame[col].dtype == '|S': data_frame[col] = data_frame[col].str.decode('utf-8') # 再正常导出CSV data_frame.to_csv(filename, sep='\t', encoding='utf-8')
这样既保留了处理过程中的内存优势,又能导出正常的字符串内容。
2. 改用内存友好的字符串类型替代|S
如果还没开始处理数据,推荐用Pandas原生的字符串类型来做内存优化,从根源避免后续导出问题:
- 如果你列的重复值很多:用
category类型,内存节省效果可能比|S更好:data_frame['COLUMN1'] = data_frame['COLUMN1'].astype('category') - 如果重复值不多,用Pandas 1.0+支持的
StringDtype():from pandas import StringDtype data_frame['COLUMN1'] = data_frame['COLUMN1'].astype(StringDtype())
这两种类型导出CSV时都会正常输出字符串,不需要额外处理。
3. 导出时直接格式化字节列
如果不想修改原DataFrame的结构,可以在导出时指定格式化函数,对字节列进行解码:
# 定义格式化函数,解码字节内容 def decode_bytes(x): if isinstance(x, bytes): return x.decode('utf-8') return x # 导出时将格式化函数应用到目标列 data_frame.to_csv( filename, sep='\t', encoding='utf-8', formatters={'COLUMN1': decode_bytes, 'COLUMN2': decode_bytes} )
这种方式适合需要保留原DataFrame字节类型的场景。
总结
astype('|S')的内存优化思路没问题,但代价是引入了字节类型的兼容性问题。上面三种方法都能解决导出异常的问题,你可以根据自己的实际场景选择最适合的方案~
内容的提问来源于stack exchange,提问作者Brett VanderHaar
相关产品推荐
相关产品推荐

