|
14 | 14 | from pandas.core.config import get_option, set_option, reset_option
|
15 | 15 | import pandas.core.common as com
|
16 | 16 | import pandas.lib as lib
|
| 17 | +from pandas.tslib import iNaT |
17 | 18 |
|
18 | 19 | import numpy as np
|
19 | 20 |
|
20 | 21 | import itertools
|
21 | 22 | import csv
|
| 23 | +from datetime import time |
22 | 24 |
|
23 | 25 | from pandas.tseries.period import PeriodIndex, DatetimeIndex
|
24 | 26 |
|
@@ -1609,7 +1611,7 @@ def format_array(values, formatter, float_format=None, na_rep='NaN',
|
1609 | 1611 | if digits is None:
|
1610 | 1612 | digits = get_option("display.precision")
|
1611 | 1613 |
|
1612 |
| - fmt_obj = fmt_klass(values, digits, na_rep=na_rep, |
| 1614 | + fmt_obj = fmt_klass(values, digits=digits, na_rep=na_rep, |
1613 | 1615 | float_format=float_format,
|
1614 | 1616 | formatter=formatter, space=space,
|
1615 | 1617 | justify=justify)
|
@@ -1704,7 +1706,7 @@ def _val(x, threshold):
|
1704 | 1706 | fmt_values = [_val(x, threshold) for x in self.values]
|
1705 | 1707 | return _trim_zeros(fmt_values, self.na_rep)
|
1706 | 1708 |
|
1707 |
| - def get_result(self): |
| 1709 | + def _format_strings(self): |
1708 | 1710 | if self.formatter is not None:
|
1709 | 1711 | fmt_values = [self.formatter(x) for x in self.values]
|
1710 | 1712 | else:
|
@@ -1732,64 +1734,124 @@ def get_result(self):
|
1732 | 1734 | fmt_str = '%% .%de' % (self.digits - 1)
|
1733 | 1735 | fmt_values = self._format_with(fmt_str)
|
1734 | 1736 |
|
1735 |
| - return _make_fixed_width(fmt_values, self.justify) |
| 1737 | + return fmt_values |
1736 | 1738 |
|
1737 | 1739 |
|
1738 | 1740 | class IntArrayFormatter(GenericArrayFormatter):
|
1739 | 1741 |
|
1740 |
| - def get_result(self): |
1741 |
| - if self.formatter: |
1742 |
| - formatter = self.formatter |
1743 |
| - else: |
1744 |
| - formatter = lambda x: '% d' % x |
| 1742 | + def _format_strings(self): |
| 1743 | + formatter = self.formatter or (lambda x: '% d' % x) |
1745 | 1744 |
|
1746 | 1745 | fmt_values = [formatter(x) for x in self.values]
|
1747 | 1746 |
|
1748 |
| - return _make_fixed_width(fmt_values, self.justify) |
| 1747 | + return fmt_values |
1749 | 1748 |
|
1750 | 1749 |
|
1751 | 1750 | class Datetime64Formatter(GenericArrayFormatter):
|
| 1751 | + def __init__(self, values, nat_rep='NaT', date_format=None, **kwargs): |
| 1752 | + super(Datetime64Formatter, self).__init__(values, **kwargs) |
| 1753 | + self.nat_rep = nat_rep |
| 1754 | + self.date_format = date_format |
1752 | 1755 |
|
1753 |
| - def get_result(self): |
1754 |
| - if self.formatter: |
1755 |
| - formatter = self.formatter |
1756 |
| - else: |
1757 |
| - formatter = _format_datetime64 |
| 1756 | + def _format_strings(self): |
| 1757 | + formatter = self.formatter or _get_format_datetime64_from_values( |
| 1758 | + self.values, |
| 1759 | + nat_rep=self.nat_rep, |
| 1760 | + date_format=self.date_format) |
1758 | 1761 |
|
1759 | 1762 | fmt_values = [formatter(x) for x in self.values]
|
1760 |
| - return _make_fixed_width(fmt_values, self.justify) |
1761 | 1763 |
|
| 1764 | + return fmt_values |
1762 | 1765 |
|
1763 |
| -def _format_datetime64(x, tz=None): |
1764 |
| - if isnull(x): |
1765 |
| - return 'NaT' |
1766 | 1766 |
|
1767 |
| - stamp = lib.Timestamp(x, tz=tz) |
1768 |
| - return stamp._repr_base |
| 1767 | +def _format_datetime64(x, tz=None, nat_rep='NaT'): |
| 1768 | + if x is None or lib.checknull(x): |
| 1769 | + return nat_rep |
1769 | 1770 |
|
| 1771 | + if tz is not None or not isinstance(x, lib.Timestamp): |
| 1772 | + x = lib.Timestamp(x, tz=tz) |
1770 | 1773 |
|
1771 |
| -class Timedelta64Formatter(Datetime64Formatter): |
| 1774 | + return str(x) |
1772 | 1775 |
|
1773 |
| - def get_result(self): |
1774 |
| - if self.formatter: |
1775 |
| - formatter = self.formatter |
1776 |
| - else: |
1777 | 1776 |
|
1778 |
| - formatter = _format_timedelta64 |
| 1777 | +def _format_datetime64_dateonly(x, nat_rep='NaT', date_format=None): |
| 1778 | + if x is None or lib.checknull(x): |
| 1779 | + return nat_rep |
| 1780 | + |
| 1781 | + if not isinstance(x, lib.Timestamp): |
| 1782 | + x = lib.Timestamp(x) |
| 1783 | + |
| 1784 | + if date_format: |
| 1785 | + return x.strftime(date_format) |
| 1786 | + else: |
| 1787 | + return x._date_repr |
| 1788 | + |
| 1789 | + |
| 1790 | +def _is_dates_only(values): |
| 1791 | + for d in values: |
| 1792 | + if isinstance(d, np.datetime64): |
| 1793 | + d = lib.Timestamp(d) |
| 1794 | + |
| 1795 | + if d is not None and not lib.checknull(d) and d._has_time_component(): |
| 1796 | + return False |
| 1797 | + return True |
| 1798 | + |
| 1799 | + |
| 1800 | +def _get_format_datetime64(is_dates_only, nat_rep='NaT', date_format=None): |
| 1801 | + |
| 1802 | + if is_dates_only: |
| 1803 | + return lambda x, tz=None: _format_datetime64_dateonly(x, |
| 1804 | + nat_rep=nat_rep, |
| 1805 | + date_format=date_format) |
| 1806 | + else: |
| 1807 | + return lambda x, tz=None: _format_datetime64(x, tz=tz, nat_rep=nat_rep) |
| 1808 | + |
| 1809 | + |
| 1810 | +def _get_format_datetime64_from_values(values, |
| 1811 | + nat_rep='NaT', |
| 1812 | + date_format=None): |
| 1813 | + is_dates_only = _is_dates_only(values) |
| 1814 | + return _get_format_datetime64(is_dates_only=is_dates_only, |
| 1815 | + nat_rep=nat_rep, |
| 1816 | + date_format=date_format) |
| 1817 | + |
| 1818 | + |
| 1819 | +class Timedelta64Formatter(GenericArrayFormatter): |
| 1820 | + |
| 1821 | + def _format_strings(self): |
| 1822 | + formatter = self.formatter or _get_format_timedelta64(self.values) |
1779 | 1823 |
|
1780 | 1824 | fmt_values = [formatter(x) for x in self.values]
|
1781 |
| - return _make_fixed_width(fmt_values, self.justify) |
1782 | 1825 |
|
| 1826 | + return fmt_values |
| 1827 | + |
| 1828 | + |
| 1829 | +def _get_format_timedelta64(values): |
| 1830 | + values_int = values.astype(np.int64) |
1783 | 1831 |
|
1784 |
| -def _format_timedelta64(x): |
1785 |
| - if isnull(x): |
1786 |
| - return 'NaT' |
| 1832 | + consider_values = values_int != iNaT |
1787 | 1833 |
|
1788 |
| - return lib.repr_timedelta64(x) |
| 1834 | + one_day_in_nanos = (86400 * 1e9) |
| 1835 | + even_days = np.logical_and(consider_values, values_int % one_day_in_nanos != 0).sum() == 0 |
| 1836 | + all_sub_day = np.logical_and(consider_values, np.abs(values_int) >= one_day_in_nanos).sum() == 0 |
| 1837 | + |
| 1838 | + format_short = even_days or all_sub_day |
| 1839 | + format = "short" if format_short else "long" |
| 1840 | + |
| 1841 | + def impl(x): |
| 1842 | + if x is None or lib.checknull(x): |
| 1843 | + return 'NaT' |
| 1844 | + elif format_short and x == 0: |
| 1845 | + return "0 days" if even_days else "00:00:00" |
| 1846 | + else: |
| 1847 | + return lib.repr_timedelta64(x, format=format) |
| 1848 | + |
| 1849 | + return impl |
1789 | 1850 |
|
1790 | 1851 |
|
1791 | 1852 | def _make_fixed_width(strings, justify='right', minimum=None, truncated=False):
|
1792 |
| - if len(strings) == 0: |
| 1853 | + |
| 1854 | + if len(strings) == 0 or justify == 'all': |
1793 | 1855 | return strings
|
1794 | 1856 |
|
1795 | 1857 | _strlen = _strlen_func()
|
|
0 commit comments