From b4b4c77046322f98d345ce068ec972f65b60c84d Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 4 Aug 2017 09:44:53 +0200 Subject: [PATCH] REF: repr - allow block to override values that get formatted (#17143) --- pandas/core/internals.py | 8 +++++ pandas/core/series.py | 6 ++++ pandas/io/formats/format.py | 6 ++-- pandas/tests/internals/__init__.py | 0 pandas/tests/internals/test_external_block.py | 29 +++++++++++++++++++ .../tests/{ => internals}/test_internals.py | 0 setup.py | 1 + 7 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 pandas/tests/internals/__init__.py create mode 100644 pandas/tests/internals/test_external_block.py rename pandas/tests/{ => internals}/test_internals.py (100%) diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 37fc1c01061ec..0f85c4e046e5a 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -160,6 +160,10 @@ def internal_values(self, dtype=None): """ return self.values + def formatting_values(self): + """Return the internal values used by the DataFrame/SeriesFormatter""" + return self.internal_values() + def get_values(self, dtype=None): """ return an internal format, currently just the ndarray @@ -4317,6 +4321,10 @@ def external_values(self): def internal_values(self): return self._block.internal_values() + def formatting_values(self): + """Return the internal values used by the DataFrame/SeriesFormatter""" + return self._block.formatting_values() + def get_values(self): """ return a dense type view """ return np.array(self._block.to_dense(), copy=False) diff --git a/pandas/core/series.py b/pandas/core/series.py index 996b483ff6092..e42ba3908a29a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -397,6 +397,12 @@ def _values(self): """ return the internal repr of this data """ return self._data.internal_values() + def _formatting_values(self): + """Return the values that can be formatted (used by SeriesFormatter + and DataFrameFormatter) + """ + return self._data.formatting_values() + def get_values(self): """ same as values (but handles sparseness conversions); is a view """ return self._data.get_values() diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 2b322431bd301..733fd3bd39b52 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -237,7 +237,8 @@ def _get_formatted_index(self): return fmt_index, have_header def _get_formatted_values(self): - return format_array(self.tr_series._values, None, + values_to_format = self.tr_series._formatting_values() + return format_array(values_to_format, None, float_format=self.float_format, na_rep=self.na_rep) def to_string(self): @@ -694,7 +695,8 @@ def to_latex(self, column_format=None, longtable=False, encoding=None, def _format_col(self, i): frame = self.tr_frame formatter = self._get_formatter(i) - return format_array(frame.iloc[:, i]._values, formatter, + values_to_format = frame.iloc[:, i]._formatting_values() + return format_array(values_to_format, formatter, float_format=self.float_format, na_rep=self.na_rep, space=self.col_space, decimal=self.decimal) diff --git a/pandas/tests/internals/__init__.py b/pandas/tests/internals/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/pandas/tests/internals/test_external_block.py b/pandas/tests/internals/test_external_block.py new file mode 100644 index 0000000000000..cccde76c3e1d9 --- /dev/null +++ b/pandas/tests/internals/test_external_block.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# pylint: disable=W0102 + +import numpy as np + +import pandas as pd +from pandas.core.internals import Block, BlockManager, SingleBlockManager + + +class CustomBlock(Block): + + def formatting_values(self): + return np.array(["Val: {}".format(i) for i in self.values]) + + +def test_custom_repr(): + values = np.arange(3, dtype='int64') + + # series + block = CustomBlock(values, placement=slice(0, 3)) + + s = pd.Series(SingleBlockManager(block, pd.RangeIndex(3))) + assert repr(s) == '0 Val: 0\n1 Val: 1\n2 Val: 2\ndtype: int64' + + # dataframe + block = CustomBlock(values.reshape(1, -1), placement=slice(0, 1)) + blk_mgr = BlockManager([block], [['col'], range(3)]) + df = pd.DataFrame(blk_mgr) + assert repr(df) == ' col\n0 Val: 0\n1 Val: 1\n2 Val: 2' diff --git a/pandas/tests/test_internals.py b/pandas/tests/internals/test_internals.py similarity index 100% rename from pandas/tests/test_internals.py rename to pandas/tests/internals/test_internals.py diff --git a/setup.py b/setup.py index d5791862cfb19..a912b25328954 100755 --- a/setup.py +++ b/setup.py @@ -670,6 +670,7 @@ def pxd(name): 'pandas.tests.indexes.datetimes', 'pandas.tests.indexes.timedeltas', 'pandas.tests.indexes.period', + 'pandas.tests.internals', 'pandas.tests.io', 'pandas.tests.io.json', 'pandas.tests.io.parser',