使用pandas to_csv保存含numpy数组的DataFrame时出现换行异常
解决numpy数组在CSV保存/读取时出现换行符的问题
嘿,我完全懂你遇到的这个麻烦——当DataFrame里包含numpy数组时,用pandas.to_csv保存再用pandas.read_csv读取,数组内部会莫名出现换行符\n,导致数据格式混乱。这背后其实是文本格式和numpy数组默认字符串表示的冲突,下面给你几个实用的解决方案:
原因分析
CSV是纯文本格式,当pandas把numpy数组写入CSV时,会直接使用数组的默认字符串输出(比如多维数组打印时自带换行),这些换行符会被保留在CSV文件里;读取时,pandas会把带换行的内容当成字符串的一部分,自然就出现了\n。
解决方案1:将numpy数组转为列表后保存(适合一维数组)
把数组转成普通列表,这样写入CSV的是逗号分隔的字符串,读取后再转回numpy数组:
import pandas as pd import numpy as np # 创建包含numpy数组的DataFrame d = {'col1': [1, 2], 'col2': [np.array([1,2,3]), np.array([4,5,6])]} df = pd.DataFrame(data=d) # 把numpy数组转为列表 df['col2'] = df['col2'].apply(lambda x: x.tolist()) # 保存CSV df.to_csv('test.csv', index=False) # 读取并转回numpy数组 df_read = pd.read_csv('test.csv') df_read['col2'] = df_read['col2'].apply(lambda x: np.array(eval(x))) print(df_read['col2'][0]) # 输出:array([1, 2, 3])
⚠️ 注意:eval虽然方便,但如果CSV里有不可信的内容会有安全风险,适合自己生成的可信数据。
解决方案2:自定义数组字符串格式(适合多维数组,更安全)
用np.array2string控制数组的字符串输出,去掉换行符和多余空格,读取时手动解析字符串:
import pandas as pd import numpy as np # 创建包含多维numpy数组的DataFrame d = {'col1': [1, 2], 'col2': [np.array([[1,2],[3,4]]), np.array([[5,6],[7,8]])]} df = pd.DataFrame(data=d) # 格式化数组字符串:去掉换行,用逗号分隔元素 df['col2'] = df['col2'].apply(lambda x: np.array2string(x, separator=',', suppress_small=True).replace('\n', '').replace(' ', '')) df.to_csv('test.csv', index=False) # 自定义函数解析字符串为numpy数组 def str_to_np_array(s): # 去掉前后的方括号,按逗号分割成数值列表 s_clean = s.strip('[]') elements = [float(num) for num in s_clean.split(',') if num] # 恢复原数组的形状(这里假设你知道原数组的形状,或者可以额外存形状信息) return np.array(elements).reshape(2,2) # 读取并转换 df_read = pd.read_csv('test.csv') df_read['col2'] = df_read['col2'].apply(str_to_np_array) print(df_read['col2'][0]) # 输出: # array([[1., 2.], # [3., 4.]])
解决方案3:用Pickle二进制格式保存(最省心,适合不需要CSV可读性的场景)
如果不需要CSV的文本可读性,直接用pandas的to_pickle和read_pickle,二进制格式能完美保留numpy数组的结构和类型,完全不会有换行符问题:
import pandas as pd import numpy as np # 创建包含numpy数组的DataFrame d = {'col1': [1, 2], 'col2': [np.array([1,2,3]), np.array([[4,5],[6,7]])]} df = pd.DataFrame(data=d) # 保存为pickle文件 df.to_pickle('test_data.pkl') # 读取pickle文件 df_read = pd.read_pickle('test_data.pkl') # 验证数组完全一致 print(df_read['col2'][0] == df['col2'][0]) # 输出:array([ True, True, True])
内容的提问来源于stack exchange,提问作者Koen
相关产品推荐
相关产品推荐

