Skip to content

Commit 230aaa5

Browse files
committed
ENH: can pass file handle or StringIO to Series.to_csv and DataFrame.to_csv, GH #765
1 parent c0fb29c commit 230aaa5

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

pandas/core/frame.py

+15-5
Original file line numberDiff line numberDiff line change
@@ -909,15 +909,15 @@ def _helper_csvexcel(self, writer, na_rep=None, cols=None, header=True,
909909

910910
writer.writerow(encoded_rows)
911911

912-
def to_csv(self, path, sep=",", na_rep='', cols=None, header=True,
913-
index=True, index_label=None, mode='w', nanRep=None,
914-
encoding=None):
912+
def to_csv(self, path_or_buf, sep=",", na_rep='', cols=None,
913+
header=True, index=True, index_label=None, mode='w',
914+
nanRep=None, encoding=None):
915915
"""
916916
Write DataFrame to a comma-separated values (csv) file
917917
918918
Parameters
919919
----------
920-
path : string
920+
path_or_buf : string or file handle / StringIO
921921
File path
922922
na_rep : string, default ''
923923
Missing data representation
@@ -944,11 +944,21 @@ def to_csv(self, path, sep=",", na_rep='', cols=None, header=True,
944944
FutureWarning)
945945
na_rep = nanRep
946946

947-
with open(path, mode) as f:
947+
if hasattr(path_or_buf, 'read'):
948+
f = path_or_buf
949+
close = False
950+
else:
951+
f = open(path_or_buf, mode)
952+
close = True
953+
954+
try:
948955
csvout = csv.writer(f, lineterminator='\n', delimiter=sep)
949956
self._helper_csvexcel(csvout, na_rep=na_rep, cols=cols,
950957
header=header, index=index,
951958
index_label=index_label, encoding=encoding)
959+
finally:
960+
if close:
961+
f.close()
952962

953963
def to_excel(self, excel_writer, sheet_name = 'sheet1', na_rep='', cols=None, header=True,
954964
index=True, index_label=None):

pandas/core/series.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2056,7 +2056,7 @@ def to_csv(self, path, index=True, sep=",", na_rep='', header=False,
20562056
from pandas.core.frame import DataFrame
20572057
df = DataFrame(self)
20582058
df.to_csv(path, index=index, sep=sep, na_rep=na_rep, header=header,
2059-
index_label=index_label,mode=mode, nanRep=nanRep,
2059+
index_label=index_label, mode=mode, nanRep=nanRep,
20602060
encoding=encoding)
20612061

20622062
def dropna(self):

pandas/tests/test_frame.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -2254,32 +2254,37 @@ def test_to_csv_withcommas(self):
22542254
os.remove(path)
22552255

22562256
def test_to_csv_bug(self):
2257-
from pandas import read_csv
22582257
path = '__tmp__.csv'
22592258
f1 = StringIO('a,1.0\nb,2.0')
22602259
df = DataFrame.from_csv(f1,header=None)
22612260
newdf = DataFrame({'t': df[df.columns[0]]})
22622261
newdf.to_csv(path)
22632262

2264-
recons = read_csv(path, index_col=0)
2263+
recons = pan.read_csv(path, index_col=0)
22652264
assert_frame_equal(recons, newdf)
22662265

22672266
os.remove(path)
22682267

22692268
def test_to_csv_unicode(self):
2270-
from pandas import read_csv
22712269
path = '__tmp__.csv'
22722270
df = DataFrame({u'c/\u03c3':[1,2,3]})
22732271
df.to_csv(path, encoding='UTF-8')
2274-
df2 = read_csv(path, index_col=0, encoding='UTF-8')
2272+
df2 = pan.read_csv(path, index_col=0, encoding='UTF-8')
22752273
assert_frame_equal(df, df2)
22762274

22772275
df.to_csv(path, encoding='UTF-8', index=False)
2278-
df2 = read_csv(path, index_col=None, encoding='UTF-8')
2276+
df2 = pan.read_csv(path, index_col=None, encoding='UTF-8')
22792277
assert_frame_equal(df, df2)
22802278

22812279
os.remove(path)
22822280

2281+
def test_to_csv_stringio(self):
2282+
buf = StringIO()
2283+
self.frame.to_csv(buf)
2284+
buf.seek(0)
2285+
recons = pan.read_csv(buf, index_col=0)
2286+
assert_frame_equal(recons, self.frame)
2287+
22832288
def test_to_excel_from_excel(self):
22842289
try:
22852290
import xlwt

pandas/tests/test_series.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# pylint: disable-msg=E1101,W0612
22

3+
from cStringIO import StringIO
34
from datetime import datetime, timedelta
45
import os
56
import operator
@@ -1515,6 +1516,13 @@ def test_to_csv(self):
15151516

15161517
os.remove('_foo')
15171518

1519+
def test_to_csv_stringio(self):
1520+
buf = StringIO()
1521+
self.ts.to_csv(buf, index=False)
1522+
buf.seek(0)
1523+
arr = np.loadtxt(buf)
1524+
assert_almost_equal(arr, self.ts.values)
1525+
15181526
def test_to_dict(self):
15191527
self.assert_(np.array_equal(Series(self.ts.to_dict()), self.ts))
15201528

0 commit comments

Comments
 (0)