Skip to content

Commit cf691ab

Browse files
committed
Make to_csv return a string in case no buffer is supplied.
Fixes issue #6061.
1 parent 48a6849 commit cf691ab

File tree

4 files changed

+20
-5
lines changed

4 files changed

+20
-5
lines changed

doc/source/release.rst

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ API Changes
7171
- ``df['col'] = value`` and ``df.loc[:,'col'] = value`` are now completely equivalent;
7272
previously the ``.loc`` would not necessarily coerce the dtype of the resultant series (:issue:`6149`)
7373
- ``dtypes`` and ``ftypes`` now return a series with ``dtype=object`` on empty containers (:issue:`5740`)
74+
- ``df.to_csv`` will now return a string of the CSV data if neither a target path nor a buffer is provided
75+
(:issue:`6061`)
7476
- The ``interpolate`` ``downcast`` keyword default has been changed from ``infer`` to
7577
``None``. This is to preseve the original dtype unless explicitly requested otherwise (:issue:`6290`).
7678
- allow a Series to utilize index methods depending on its index type, e.g. ``Series.year`` is now defined

pandas/core/format.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ def grouper(x):
943943

944944
class CSVFormatter(object):
945945

946-
def __init__(self, obj, path_or_buf, sep=",", na_rep='', float_format=None,
946+
def __init__(self, obj, path_or_buf=None, sep=",", na_rep='', float_format=None,
947947
cols=None, header=True, index=True, index_label=None,
948948
mode='w', nanRep=None, encoding=None, quoting=None,
949949
line_terminator='\n', chunksize=None, engine=None,
@@ -953,6 +953,9 @@ def __init__(self, obj, path_or_buf, sep=",", na_rep='', float_format=None,
953953
self.engine = engine # remove for 0.13
954954
self.obj = obj
955955

956+
if path_or_buf is None:
957+
path_or_buf = StringIO()
958+
956959
self.path_or_buf = path_or_buf
957960
self.sep = sep
958961
self.na_rep = na_rep
@@ -1144,7 +1147,7 @@ def strftime_with_nulls(x):
11441147

11451148
def save(self):
11461149
# create the writer & save
1147-
if hasattr(self.path_or_buf, 'read'):
1150+
if hasattr(self.path_or_buf, 'write'):
11481151
f = self.path_or_buf
11491152
close = False
11501153
else:

pandas/core/frame.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ def to_panel(self):
10671067

10681068
to_wide = deprecate('to_wide', to_panel)
10691069

1070-
def to_csv(self, path_or_buf, sep=",", na_rep='', float_format=None,
1070+
def to_csv(self, path_or_buf=None, sep=",", na_rep='', float_format=None,
10711071
cols=None, header=True, index=True, index_label=None,
10721072
mode='w', nanRep=None, encoding=None, quoting=None,
10731073
quotechar='"', line_terminator='\n', chunksize=None,
@@ -1077,8 +1077,9 @@ def to_csv(self, path_or_buf, sep=",", na_rep='', float_format=None,
10771077
10781078
Parameters
10791079
----------
1080-
path_or_buf : string or file handle / StringIO
1081-
File path
1080+
path_or_buf : string or file handle, default None
1081+
File path or object, if None is provided the result is returned as
1082+
a string.
10821083
sep : character, default ","
10831084
Field delimiter for the output file.
10841085
na_rep : string, default ''
@@ -1144,6 +1145,9 @@ def to_csv(self, path_or_buf, sep=",", na_rep='', float_format=None,
11441145
escapechar=escapechar)
11451146
formatter.save()
11461147

1148+
if path_or_buf is None:
1149+
return formatter.path_or_buf.getvalue()
1150+
11471151
def to_excel(self, excel_writer, sheet_name='Sheet1', na_rep='',
11481152
float_format=None, cols=None, header=True, index=True,
11491153
index_label=None, startrow=0, startcol=0, engine=None,

pandas/tests/test_format.py

+6
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,12 @@ def test_to_csv_escapechar(self):
17871787
with open(path, 'r') as f:
17881788
self.assertEqual(f.read(), expected)
17891789

1790+
def test_csv_to_string(self):
1791+
df = DataFrame({'col' : [1,2]})
1792+
expected = ',col\n0,1\n1,2\n'
1793+
self.assertEqual(df.to_csv(), expected)
1794+
1795+
17901796
class TestSeriesFormatting(tm.TestCase):
17911797
_multiprocess_can_split_ = True
17921798

0 commit comments

Comments
 (0)