From cf691abcf5eccc96a6108d6b87252b768390fdf0 Mon Sep 17 00:00:00 2001 From: Benedikt Sauer Date: Wed, 19 Feb 2014 09:31:15 +0100 Subject: [PATCH] Make to_csv return a string in case no buffer is supplied. Fixes issue #6061. --- doc/source/release.rst | 2 ++ pandas/core/format.py | 7 +++++-- pandas/core/frame.py | 10 +++++++--- pandas/tests/test_format.py | 6 ++++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/doc/source/release.rst b/doc/source/release.rst index 267f373a9e534..5c7d090becf83 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -71,6 +71,8 @@ API Changes - ``df['col'] = value`` and ``df.loc[:,'col'] = value`` are now completely equivalent; previously the ``.loc`` would not necessarily coerce the dtype of the resultant series (:issue:`6149`) - ``dtypes`` and ``ftypes`` now return a series with ``dtype=object`` on empty containers (:issue:`5740`) +- ``df.to_csv`` will now return a string of the CSV data if neither a target path nor a buffer is provided + (:issue:`6061`) - The ``interpolate`` ``downcast`` keyword default has been changed from ``infer`` to ``None``. This is to preseve the original dtype unless explicitly requested otherwise (:issue:`6290`). - allow a Series to utilize index methods depending on its index type, e.g. ``Series.year`` is now defined diff --git a/pandas/core/format.py b/pandas/core/format.py index 04413970440b9..537fdc6cd0a27 100644 --- a/pandas/core/format.py +++ b/pandas/core/format.py @@ -943,7 +943,7 @@ def grouper(x): class CSVFormatter(object): - def __init__(self, obj, path_or_buf, sep=",", na_rep='', float_format=None, + def __init__(self, obj, path_or_buf=None, sep=",", na_rep='', float_format=None, cols=None, header=True, index=True, index_label=None, mode='w', nanRep=None, encoding=None, quoting=None, line_terminator='\n', chunksize=None, engine=None, @@ -953,6 +953,9 @@ def __init__(self, obj, path_or_buf, sep=",", na_rep='', float_format=None, self.engine = engine # remove for 0.13 self.obj = obj + if path_or_buf is None: + path_or_buf = StringIO() + self.path_or_buf = path_or_buf self.sep = sep self.na_rep = na_rep @@ -1144,7 +1147,7 @@ def strftime_with_nulls(x): def save(self): # create the writer & save - if hasattr(self.path_or_buf, 'read'): + if hasattr(self.path_or_buf, 'write'): f = self.path_or_buf close = False else: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 6885ce95a8505..134ca9a87aeb8 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1067,7 +1067,7 @@ def to_panel(self): to_wide = deprecate('to_wide', to_panel) - def to_csv(self, path_or_buf, sep=",", na_rep='', float_format=None, + def to_csv(self, path_or_buf=None, sep=",", na_rep='', float_format=None, cols=None, header=True, index=True, index_label=None, mode='w', nanRep=None, encoding=None, quoting=None, quotechar='"', line_terminator='\n', chunksize=None, @@ -1077,8 +1077,9 @@ def to_csv(self, path_or_buf, sep=",", na_rep='', float_format=None, Parameters ---------- - path_or_buf : string or file handle / StringIO - File path + path_or_buf : string or file handle, default None + File path or object, if None is provided the result is returned as + a string. sep : character, default "," Field delimiter for the output file. na_rep : string, default '' @@ -1144,6 +1145,9 @@ def to_csv(self, path_or_buf, sep=",", na_rep='', float_format=None, escapechar=escapechar) formatter.save() + if path_or_buf is None: + return formatter.path_or_buf.getvalue() + def to_excel(self, excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, cols=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py index 917e6daf39437..5296be15f242e 100644 --- a/pandas/tests/test_format.py +++ b/pandas/tests/test_format.py @@ -1787,6 +1787,12 @@ def test_to_csv_escapechar(self): with open(path, 'r') as f: self.assertEqual(f.read(), expected) + def test_csv_to_string(self): + df = DataFrame({'col' : [1,2]}) + expected = ',col\n0,1\n1,2\n' + self.assertEqual(df.to_csv(), expected) + + class TestSeriesFormatting(tm.TestCase): _multiprocess_can_split_ = True