diff --git a/doc/source/api.rst b/doc/source/api.rst index 638abd5421862..929664840f583 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -692,6 +692,7 @@ Serialization / IO / Conversion Series.to_pickle Series.to_csv Series.to_dict + Series.to_excel Series.to_frame Series.to_xarray Series.to_hdf diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index f172f70932d60..93c177428d0c2 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -49,8 +49,8 @@ Other enhancements ^^^^^^^^^^^^^^^^^^ - ``pd.read_excel`` now preserves sheet order when using ``sheetname=None`` (:issue:`9930`) - - ``pd.cut`` and ``pd.qcut`` now support datetime64 and timedelta64 dtypes (issue:`14714`) +- ``Series`` provides a ``to_excel`` method to output Excel files (:issue:`8825`) .. _whatsnew_0200.api_breaking: @@ -105,4 +105,4 @@ Performance Improvements .. _whatsnew_0200.bug_fixes: Bug Fixes -~~~~~~~~~ +~~~~~~~~~ \ No newline at end of file diff --git a/pandas/core/frame.py b/pandas/core/frame.py index bf1ff28cd63b1..4cb26ab2f5886 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -105,7 +105,8 @@ axes_single_arg="{0 or 'index', 1 or 'columns'}", optional_by=""" by : str or list of str - Name or list of names which refer to the axis items.""") + Name or list of names which refer to the axis items.""", + versionadded_to_excel='') _numeric_only_doc = """numeric_only : boolean, default None Include only float, int, boolean data. If None, will attempt to use @@ -1385,65 +1386,11 @@ def to_csv(self, path_or_buf=None, sep=",", na_rep='', float_format=None, if path_or_buf is None: return formatter.path_or_buf.getvalue() + @Appender(_shared_docs['to_excel'] % _shared_doc_kwargs) def to_excel(self, excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True): - """ - Write DataFrame to a excel sheet - - Parameters - ---------- - excel_writer : string or ExcelWriter object - File path or existing ExcelWriter - sheet_name : string, default 'Sheet1' - Name of sheet which will contain DataFrame - na_rep : string, default '' - Missing data representation - float_format : string, default None - Format string for floating point numbers - columns : sequence, optional - Columns to write - header : boolean or list of string, default True - Write out column names. If a list of string is given it is - assumed to be aliases for the column names - index : boolean, default True - Write row names (index) - index_label : string or sequence, default None - Column label for index column(s) if desired. If None is given, and - `header` and `index` are True, then the index names are used. A - sequence should be given if the DataFrame uses MultiIndex. - startrow : - upper left cell row to dump data frame - startcol : - upper left cell column to dump data frame - engine : string, default None - write engine to use - you can also set this via the options - ``io.excel.xlsx.writer``, ``io.excel.xls.writer``, and - ``io.excel.xlsm.writer``. - merge_cells : boolean, default True - Write MultiIndex and Hierarchical Rows as merged cells. - encoding: string, default None - encoding of the resulting excel file. Only necessary for xlwt, - other writers support unicode natively. - inf_rep : string, default 'inf' - Representation for infinity (there is no native representation for - infinity in Excel) - - Notes - ----- - If passing an existing ExcelWriter object, then the sheet will be added - to the existing workbook. This can be used to save different - DataFrames to one workbook: - - >>> writer = ExcelWriter('output.xlsx') - >>> df1.to_excel(writer,'Sheet1') - >>> df2.to_excel(writer,'Sheet2') - >>> writer.save() - - For compatibility with to_csv, to_excel serializes lists and dicts to - strings before writing. - """ from pandas.io.excel import ExcelWriter need_save = False if encoding is None: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 7868969f477b0..c25ff7d8a318b 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1016,6 +1016,62 @@ def __setstate__(self, state): # ---------------------------------------------------------------------- # I/O Methods + _shared_docs['to_excel'] = """ + Write %(klass)s to a excel sheet + %(versionadded_to_excel)s + Parameters + ---------- + excel_writer : string or ExcelWriter object + File path or existing ExcelWriter + sheet_name : string, default 'Sheet1' + Name of sheet which will contain DataFrame + na_rep : string, default '' + Missing data representation + float_format : string, default None + Format string for floating point numbers + columns : sequence, optional + Columns to write + header : boolean or list of string, default True + Write out column names. If a list of string is given it is + assumed to be aliases for the column names + index : boolean, default True + Write row names (index) + index_label : string or sequence, default None + Column label for index column(s) if desired. If None is given, and + `header` and `index` are True, then the index names are used. A + sequence should be given if the DataFrame uses MultiIndex. + startrow : + upper left cell row to dump data frame + startcol : + upper left cell column to dump data frame + engine : string, default None + write engine to use - you can also set this via the options + ``io.excel.xlsx.writer``, ``io.excel.xls.writer``, and + ``io.excel.xlsm.writer``. + merge_cells : boolean, default True + Write MultiIndex and Hierarchical Rows as merged cells. + encoding: string, default None + encoding of the resulting excel file. Only necessary for xlwt, + other writers support unicode natively. + inf_rep : string, default 'inf' + Representation for infinity (there is no native representation for + infinity in Excel) + + Notes + ----- + If passing an existing ExcelWriter object, then the sheet will be added + to the existing workbook. This can be used to save different + DataFrames to one workbook: + + >>> writer = ExcelWriter('output.xlsx') + >>> df1.to_excel(writer,'Sheet1') + >>> df2.to_excel(writer,'Sheet2') + >>> writer.save() + + For compatibility with to_csv, to_excel serializes lists and dicts to + strings before writing. + """ + def to_json(self, path_or_buf=None, orient=None, date_format='epoch', double_precision=10, force_ascii=True, date_unit='ms', default_handler=None, lines=False): diff --git a/pandas/core/series.py b/pandas/core/series.py index 56a3933bded3b..dc4eb3f0eba26 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -80,7 +80,8 @@ inplace="""inplace : boolean, default False If True, performs operation inplace and returns None.""", unique='np.ndarray', duplicated='Series', - optional_by='') + optional_by='', + versionadded_to_excel='\n.. versionadded:: 0.20.0\n') def _coerce_method(converter): @@ -2619,6 +2620,19 @@ def to_csv(self, path=None, index=True, sep=",", na_rep='', if path is None: return result + @Appender(generic._shared_docs['to_excel'] % _shared_doc_kwargs) + def to_excel(self, excel_writer, sheet_name='Sheet1', na_rep='', + float_format=None, columns=None, header=True, index=True, + index_label=None, startrow=0, startcol=0, engine=None, + merge_cells=True, encoding=None, inf_rep='inf', verbose=True): + df = self.to_frame() + df.to_excel(excel_writer=excel_writer, sheet_name=sheet_name, + na_rep=na_rep, float_format=float_format, columns=columns, + header=header, index=index, index_label=index_label, + startrow=startrow, startcol=startcol, engine=engine, + merge_cells=merge_cells, encoding=encoding, + inf_rep=inf_rep, verbose=verbose) + def dropna(self, axis=0, inplace=False, **kwargs): """ Return Series without null values diff --git a/pandas/io/tests/test_excel.py b/pandas/io/tests/test_excel.py index 9c909398d2d88..7a1b5655cfbf7 100644 --- a/pandas/io/tests/test_excel.py +++ b/pandas/io/tests/test_excel.py @@ -1078,6 +1078,12 @@ def test_roundtrip(self): recons = read_excel(path, index_col=0) tm.assert_frame_equal(self.frame, recons) + # GH 8825 Pandas Series should provide to_excel method + s = self.frame["A"] + s.to_excel(path) + recons = read_excel(path, index_col=0) + tm.assert_frame_equal(s.to_frame(), recons) + def test_mixed(self): _skip_if_no_xlrd()