diff --git a/pandas/io/excel.py b/pandas/io/excel.py index 6b83fada19001..44b323abf45c2 100644 --- a/pandas/io/excel.py +++ b/pandas/io/excel.py @@ -16,6 +16,7 @@ from pandas.core import config from pandas.core.common import pprint_thing import pandas.compat as compat +import pandas.core.common as com from warnings import warn __all__ = ["read_excel", "ExcelWriter", "ExcelFile"] @@ -290,7 +291,6 @@ def __enter__(self): def __exit__(self, exc_type, exc_value, traceback): self.close() - def _trim_excel_header(row): # trim header row so auto-index inference works # xlrd uses '' , openpyxl None @@ -298,12 +298,13 @@ def _trim_excel_header(row): row = row[1:] return row - def _conv_value(val): - # convert value for excel dump - if isinstance(val, np.int64): + # Convert numpy types to Python types for the Excel writers. + if com.is_integer(val): val = int(val) - elif isinstance(val, np.bool8): + elif com.is_float(val): + val = float(val) + elif com.is_bool(val): val = bool(val) elif isinstance(val, Period): val = "%s" % val @@ -686,8 +687,6 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0): style_dict = {} for cell in cells: - val = _conv_value(cell.val) - num_format_str = None if isinstance(cell.val, datetime.datetime): num_format_str = "YYYY-MM-DD HH:MM:SS" @@ -709,11 +708,11 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0): startrow + cell.mergestart, startcol + cell.col, startcol + cell.mergeend, - val, style) + cell.val, style) else: wks.write(startrow + cell.row, startcol + cell.col, - val, style) + cell.val, style) def _convert_to_style(self, style_dict, num_format_str=None): """ diff --git a/pandas/io/tests/test_excel.py b/pandas/io/tests/test_excel.py index 38b3ee192ab7a..b279c7ffd2892 100644 --- a/pandas/io/tests/test_excel.py +++ b/pandas/io/tests/test_excel.py @@ -221,7 +221,6 @@ def test_excel_table_sheet_by_index(self): (self.xlsx1, self.csv1)]: self.check_excel_table_sheet_by_index(filename, csvfile) - def test_excel_table(self): _skip_if_no_xlrd() @@ -405,7 +404,6 @@ def test_mixed(self): recons = reader.parse('test1', index_col=0) tm.assert_frame_equal(self.mixed_frame, recons) - def test_tsframe(self): _skip_if_no_xlrd() ext = self.ext @@ -419,45 +417,70 @@ def test_tsframe(self): recons = reader.parse('test1') tm.assert_frame_equal(df, recons) - def test_int64(self): + def test_int_types(self): _skip_if_no_xlrd() ext = self.ext - path = '__tmp_to_excel_from_excel_int64__.' + ext - - with ensure_clean(path) as path: - self.frame['A'][:5] = nan - - self.frame.to_excel(path, 'test1') - self.frame.to_excel(path, 'test1', cols=['A', 'B']) - self.frame.to_excel(path, 'test1', header=False) - self.frame.to_excel(path, 'test1', index=False) + path = '__tmp_to_excel_from_excel_int_types__.' + ext - # Test np.int64, values read come back as float - frame = DataFrame(np.random.randint(-10, 10, size=(10, 2)), dtype=np.int64) - frame.to_excel(path, 'test1') - reader = ExcelFile(path) - recons = reader.parse('test1').astype(np.int64) - tm.assert_frame_equal(frame, recons, check_dtype=False) + for np_type in (np.int8, np.int16, np.int32, np.int64): - def test_bool(self): + with ensure_clean(path) as path: + self.frame['A'][:5] = nan + + self.frame.to_excel(path, 'test1') + self.frame.to_excel(path, 'test1', cols=['A', 'B']) + self.frame.to_excel(path, 'test1', header=False) + self.frame.to_excel(path, 'test1', index=False) + + # Test np.int values read come back as float. + frame = DataFrame(np.random.randint(-10, 10, size=(10, 2)), + dtype=np_type) + frame.to_excel(path, 'test1') + reader = ExcelFile(path) + recons = reader.parse('test1').astype(np_type) + tm.assert_frame_equal(frame, recons, check_dtype=False) + + def test_float_types(self): _skip_if_no_xlrd() ext = self.ext - path = '__tmp_to_excel_from_excel_bool__.' + ext + path = '__tmp_to_excel_from_excel_float_types__.' + ext - with ensure_clean(path) as path: - self.frame['A'][:5] = nan + for np_type in (np.float16, np.float32, np.float64): + with ensure_clean(path) as path: + self.frame['A'][:5] = nan - self.frame.to_excel(path, 'test1') - self.frame.to_excel(path, 'test1', cols=['A', 'B']) - self.frame.to_excel(path, 'test1', header=False) - self.frame.to_excel(path, 'test1', index=False) + self.frame.to_excel(path, 'test1') + self.frame.to_excel(path, 'test1', cols=['A', 'B']) + self.frame.to_excel(path, 'test1', header=False) + self.frame.to_excel(path, 'test1', index=False) - # Test reading/writing np.bool8, roundtrip only works for xlsx - frame = (DataFrame(np.random.randn(10, 2)) >= 0) - frame.to_excel(path, 'test1') - reader = ExcelFile(path) - recons = reader.parse('test1').astype(np.bool8) - tm.assert_frame_equal(frame, recons) + # Test np.float values read come back as float. + frame = DataFrame(np.random.random_sample(10), dtype=np_type) + frame.to_excel(path, 'test1') + reader = ExcelFile(path) + recons = reader.parse('test1').astype(np_type) + tm.assert_frame_equal(frame, recons, check_dtype=False) + + def test_bool_types(self): + _skip_if_no_xlrd() + ext = self.ext + path = '__tmp_to_excel_from_excel_bool_types__.' + ext + + for np_type in (np.bool8, np.bool_): + with ensure_clean(path) as path: + self.frame['A'][:5] = nan + + self.frame.to_excel(path, 'test1') + self.frame.to_excel(path, 'test1', cols=['A', 'B']) + self.frame.to_excel(path, 'test1', header=False) + self.frame.to_excel(path, 'test1', index=False) + + # Test np.bool values read come back as float. + frame = (DataFrame([1, 0, True, False], dtype=np_type)) + frame.to_excel(path, 'test1') + reader = ExcelFile(path) + recons = reader.parse('test1').astype(np_type) + tm.assert_frame_equal(frame, recons) def test_sheets(self): _skip_if_no_xlrd()