将 pandas DataFrame 写入 CSV 文件
- 2024-12-17 08:30:00
- admin 原创
- 133
问题描述:
我在 Pandas 中有一个数据框,我想将其写入 CSV 文件。
我使用以下方法进行此操作:
df.to_csv('out.csv')
并出现以下错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'/u03b1' in position 20: ordinal not in range(128)
有什么方法可以轻松解决这个问题(即我的数据框中有unicode字符)?
有没有办法使用例如“to-tab”方法(我认为不存在)来写入制表符分隔的文件而不是 CSV?
解决方案 1:
要通过制表符分隔,您可以使用sep
以下参数to_csv
:
df.to_csv(file_name, sep=' ')
要使用特定编码(例如'utf-8')请使用以下encoding
参数:
df.to_csv(file_name, sep=' ', encoding='utf-8')
在许多情况下,您会想要删除索引并添加标题:
df.to_csv(file_name, sep=' ', encoding='utf-8', index=False, header=True)
解决方案 2:
当您使用该方法将DataFrame
对象存储到csv 文件to_csv
中时,您可能不需要存储对象每行前面的索引。DataFrame
您可以通过向参数传递布尔值来避免这种情况。False
`index`
有点像:
df.to_csv(file_name, encoding='utf-8', index=False)
因此,如果您的 DataFrame 对象类似于:
Color Number
0 red 22
1 blue 10
csv 文件将存储:
Color,Number
red,22
blue,10
而不是(传递默认值的 情况)True
,Color,Number
0,red,22
1,blue,10
解决方案 3:
要将 pandas DataFrame 写入 CSV 文件,您需要DataFrame.to_csv
。此函数提供许多具有合理默认值的参数,您通常需要重写这些参数以适合您的特定用例。例如,您可能希望使用不同的分隔符、更改日期时间格式或在写入时删除索引。to_csv
有您可以传递的参数来满足这些要求。
下表列出了写入 CSV 文件的一些常见场景以及可以使用的相应参数。
脚注
默认分隔符假定为逗号 (
','
)。除非您知道需要,否则请不要更改此设置。默认情况下,的索引
df
被写为第一列。如果你的 DataFrame 没有索引(换句话说,是df.index
默认的RangeIndex
),那么你需要index=False
在写入时设置。换一种方式解释,如果你的数据确实有索引,你可以(也应该)使用index=True
或完全省略它(因为默认是True
)。如果您要写入字符串数据,最好设置此参数,以便其他应用程序知道如何读取您的数据。这还可以避免
UnicodeEncodeError
您在保存时可能遇到的任何潜在问题。如果要将大型 DataFrames(>100K 行)写入磁盘,建议进行压缩,因为这样输出文件会小得多。另一方面,这意味着写入时间会增加(因此,读取时间也会增加,因为文件需要解压)。
解决方案 4:
在 Windows 上以完整路径导出文件的示例,假设您的文件有标题:
df.to_csv (r'C:UsersJohnDesktopexport_dataframe.csv', index = None, header=True)
例如,如果您想将文件存储在脚本所在的同一目录中,使用utf-8 编码并使用制表符作为分隔符:
df.to_csv(r'./export/dftocsv.csv', sep=' ', encoding='utf-8', header='true')
解决方案 5:
如果您在编码为“utf-8”时遇到问题并想逐个单元格进行操作,您可以尝试其他方法,您可以尝试以下操作。
Python 2
(其中“df”是您的 DataFrame 对象。)
for column in df.columns:
for idx in df[column].index:
x = df.get_value(idx,column)
try:
x = unicode(x.encode('utf-8','ignore'),errors ='ignore') if type(x) == unicode else unicode(str(x),errors='ignore')
df.set_value(idx,column,x)
except Exception:
print 'encoding error: {0} {1}'.format(idx,column)
df.set_value(idx,column,'')
continue
然后尝试:
df.to_csv(file_name)
您可以通过以下方式检查列的编码:
for column in df.columns:
print '{0} {1}'.format(str(type(df[column][0])),str(column))
警告:errors='ignore' 将忽略字符,例如
IN: unicode('Regenexxxae',errors='ignore')
OUT: u'Regenexx'
Python 3
for column in df.columns:
for idx in df[column].index:
x = df.get_value(idx,column)
try:
x = x if type(x) == str else str(x).encode('utf-8','ignore').decode('utf-8','ignore')
df.set_value(idx,column,x)
except Exception:
print('encoding error: {0} {1}'.format(idx,column))
df.set_value(idx,column,'')
continue
解决方案 6:
如果上述解决方案对任何人都不起作用或者 CSV 变得混乱,只需sep=' '
像这样从行中删除:
df.to_csv(file_name, encoding='utf-8')
解决方案 7:
如果您指定 UTF-8 编码,有时也会遇到这些问题。我建议您在读取文件时指定编码,并在写入文件时指定相同的编码。这可能会解决您的问题。
解决方案 8:
这可能不是这种情况的答案,但由于我尝试了相同的错误消息.to_csv
,.toCSV('name.csv')
并且错误消息不同(“ SparseDataFrame' object has no attribute 'toCSV'
)。因此,通过将数据框转换为密集数据框解决了该问题
df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
解决方案 9:
我会避免使用' '
单独的,因为这会在再次读取数据集时产生问题。
df.to_csv(file_name, encoding='utf-8')
解决方案 10:
1.errors=
有时很有用
如果文件必须采用某种编码,但现有数据框中存在无法表示的字符,errors=
则可用于“强制”无论如何都要保存数据,但代价是丢失信息。所有可以作为Python 中函数参数errors=
传递的可能值都可以在此处传递。open()
例如,下面的代码使用 ascii 编码保存 csv,其中日语字符被替换为?
。
df = pd.DataFrame({'A': ['Shohei Ohtani は一生に一度の選手だ。']})
df.to_csv('data1.csv', encoding='ascii', errors='replace', index=False)
print(pd.read_csv('data1.csv'))
A
0 Shohei Ohtani ???????????
2.float_format=
有时很有用
您可以使用 格式化浮点数据类型float_format=
,这样做有时会节省大量内存,但代价是损失精度。例如,
df = pd.DataFrame({'A': [*range(1,9,3)]*1000})/3
df.to_csv('data1.csv', index=False) # 61,440 bytes on disk
df.to_csv('data2.csv', index=False, float_format='%.2f') # 20,480 bytes on disk
3. 保存压缩的 csv
从 pandas 1.0.0 开始,你可以将一个字典传递给 compression,该字典指定存档内的压缩方法和文件名。以下代码创建一个名为 的 zip 文件compressed_data.zip
,其中包含一个名为 的文件data.csv
。
df.to_csv('compressed_data.zip', index=False, compression={'method': 'zip', 'archive_name': 'data.csv'})
# read the archived file as a csv
pd.read_csv('compressed_data.zip')
您甚至可以添加到现有档案中;只需传递即可mode='a'
。
df.to_csv('compressed_data.zip', compression={'method': 'zip', 'archive_name': 'data_new.csv'}, mode='a')