|
| 1 | +import numpy as np |
| 2 | +import pandas as pd |
| 3 | +from pandas import DataFrame |
| 4 | +from pandas.compat import u |
| 5 | +import pandas.formats.format as fmt |
| 6 | +from pandas.util import testing as tm |
| 7 | + |
| 8 | + |
| 9 | +class TestEngFormatter(tm.TestCase): |
| 10 | + |
| 11 | + def test_eng_float_formatter(self): |
| 12 | + df = DataFrame({'A': [1.41, 141., 14100, 1410000.]}) |
| 13 | + |
| 14 | + fmt.set_eng_float_format() |
| 15 | + result = df.to_string() |
| 16 | + expected = (' A\n' |
| 17 | + '0 1.410E+00\n' |
| 18 | + '1 141.000E+00\n' |
| 19 | + '2 14.100E+03\n' |
| 20 | + '3 1.410E+06') |
| 21 | + self.assertEqual(result, expected) |
| 22 | + |
| 23 | + fmt.set_eng_float_format(use_eng_prefix=True) |
| 24 | + result = df.to_string() |
| 25 | + expected = (' A\n' |
| 26 | + '0 1.410\n' |
| 27 | + '1 141.000\n' |
| 28 | + '2 14.100k\n' |
| 29 | + '3 1.410M') |
| 30 | + self.assertEqual(result, expected) |
| 31 | + |
| 32 | + fmt.set_eng_float_format(accuracy=0) |
| 33 | + result = df.to_string() |
| 34 | + expected = (' A\n' |
| 35 | + '0 1E+00\n' |
| 36 | + '1 141E+00\n' |
| 37 | + '2 14E+03\n' |
| 38 | + '3 1E+06') |
| 39 | + self.assertEqual(result, expected) |
| 40 | + |
| 41 | + self.reset_display_options() |
| 42 | + |
| 43 | + def compare(self, formatter, input, output): |
| 44 | + formatted_input = formatter(input) |
| 45 | + msg = ("formatting of %s results in '%s', expected '%s'" % |
| 46 | + (str(input), formatted_input, output)) |
| 47 | + self.assertEqual(formatted_input, output, msg) |
| 48 | + |
| 49 | + def compare_all(self, formatter, in_out): |
| 50 | + """ |
| 51 | + Parameters: |
| 52 | + ----------- |
| 53 | + formatter: EngFormatter under test |
| 54 | + in_out: list of tuples. Each tuple = (number, expected_formatting) |
| 55 | +
|
| 56 | + It is tested if 'formatter(number) == expected_formatting'. |
| 57 | + *number* should be >= 0 because formatter(-number) == fmt is also |
| 58 | + tested. *fmt* is derived from *expected_formatting* |
| 59 | + """ |
| 60 | + for input, output in in_out: |
| 61 | + self.compare(formatter, input, output) |
| 62 | + self.compare(formatter, -input, "-" + output[1:]) |
| 63 | + |
| 64 | + def test_exponents_with_eng_prefix(self): |
| 65 | + formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True) |
| 66 | + f = np.sqrt(2) |
| 67 | + in_out = [ |
| 68 | + (f * 10 ** -24, " 1.414y"), (f * 10 ** -23, " 14.142y"), |
| 69 | + (f * 10 ** -22, " 141.421y"), (f * 10 ** -21, " 1.414z"), |
| 70 | + (f * 10 ** -20, " 14.142z"), (f * 10 ** -19, " 141.421z"), |
| 71 | + (f * 10 ** -18, " 1.414a"), (f * 10 ** -17, " 14.142a"), |
| 72 | + (f * 10 ** -16, " 141.421a"), (f * 10 ** -15, " 1.414f"), |
| 73 | + (f * 10 ** -14, " 14.142f"), (f * 10 ** -13, " 141.421f"), |
| 74 | + (f * 10 ** -12, " 1.414p"), (f * 10 ** -11, " 14.142p"), |
| 75 | + (f * 10 ** -10, " 141.421p"), (f * 10 ** -9, " 1.414n"), |
| 76 | + (f * 10 ** -8, " 14.142n"), (f * 10 ** -7, " 141.421n"), |
| 77 | + (f * 10 ** -6, " 1.414u"), (f * 10 ** -5, " 14.142u"), |
| 78 | + (f * 10 ** -4, " 141.421u"), (f * 10 ** -3, " 1.414m"), |
| 79 | + (f * 10 ** -2, " 14.142m"), (f * 10 ** -1, " 141.421m"), |
| 80 | + (f * 10 ** 0, " 1.414"), (f * 10 ** 1, " 14.142"), |
| 81 | + (f * 10 ** 2, " 141.421"), (f * 10 ** 3, " 1.414k"), |
| 82 | + (f * 10 ** 4, " 14.142k"), (f * 10 ** 5, " 141.421k"), |
| 83 | + (f * 10 ** 6, " 1.414M"), (f * 10 ** 7, " 14.142M"), |
| 84 | + (f * 10 ** 8, " 141.421M"), (f * 10 ** 9, " 1.414G"), |
| 85 | + (f * 10 ** 10, " 14.142G"), (f * 10 ** 11, " 141.421G"), |
| 86 | + (f * 10 ** 12, " 1.414T"), (f * 10 ** 13, " 14.142T"), |
| 87 | + (f * 10 ** 14, " 141.421T"), (f * 10 ** 15, " 1.414P"), |
| 88 | + (f * 10 ** 16, " 14.142P"), (f * 10 ** 17, " 141.421P"), |
| 89 | + (f * 10 ** 18, " 1.414E"), (f * 10 ** 19, " 14.142E"), |
| 90 | + (f * 10 ** 20, " 141.421E"), (f * 10 ** 21, " 1.414Z"), |
| 91 | + (f * 10 ** 22, " 14.142Z"), (f * 10 ** 23, " 141.421Z"), |
| 92 | + (f * 10 ** 24, " 1.414Y"), (f * 10 ** 25, " 14.142Y"), |
| 93 | + (f * 10 ** 26, " 141.421Y")] |
| 94 | + self.compare_all(formatter, in_out) |
| 95 | + |
| 96 | + def test_exponents_without_eng_prefix(self): |
| 97 | + formatter = fmt.EngFormatter(accuracy=4, use_eng_prefix=False) |
| 98 | + f = np.pi |
| 99 | + in_out = [ |
| 100 | + (f * 10 ** -24, " 3.1416E-24"), |
| 101 | + (f * 10 ** -23, " 31.4159E-24"), |
| 102 | + (f * 10 ** -22, " 314.1593E-24"), |
| 103 | + (f * 10 ** -21, " 3.1416E-21"), |
| 104 | + (f * 10 ** -20, " 31.4159E-21"), |
| 105 | + (f * 10 ** -19, " 314.1593E-21"), |
| 106 | + (f * 10 ** -18, " 3.1416E-18"), |
| 107 | + (f * 10 ** -17, " 31.4159E-18"), |
| 108 | + (f * 10 ** -16, " 314.1593E-18"), |
| 109 | + (f * 10 ** -15, " 3.1416E-15"), |
| 110 | + (f * 10 ** -14, " 31.4159E-15"), |
| 111 | + (f * 10 ** -13, " 314.1593E-15"), |
| 112 | + (f * 10 ** -12, " 3.1416E-12"), |
| 113 | + (f * 10 ** -11, " 31.4159E-12"), |
| 114 | + (f * 10 ** -10, " 314.1593E-12"), |
| 115 | + (f * 10 ** -9, " 3.1416E-09"), |
| 116 | + (f * 10 ** -8, " 31.4159E-09"), |
| 117 | + (f * 10 ** -7, " 314.1593E-09"), |
| 118 | + (f * 10 ** -6, " 3.1416E-06"), |
| 119 | + (f * 10 ** -5, " 31.4159E-06"), |
| 120 | + (f * 10 ** -4, " 314.1593E-06"), |
| 121 | + (f * 10 ** -3, " 3.1416E-03"), |
| 122 | + (f * 10 ** -2, " 31.4159E-03"), |
| 123 | + (f * 10 ** -1, " 314.1593E-03"), |
| 124 | + (f * 10 ** 0, " 3.1416E+00"), |
| 125 | + (f * 10 ** 1, " 31.4159E+00"), |
| 126 | + (f * 10 ** 2, " 314.1593E+00"), |
| 127 | + (f * 10 ** 3, " 3.1416E+03"), |
| 128 | + (f * 10 ** 4, " 31.4159E+03"), |
| 129 | + (f * 10 ** 5, " 314.1593E+03"), |
| 130 | + (f * 10 ** 6, " 3.1416E+06"), |
| 131 | + (f * 10 ** 7, " 31.4159E+06"), |
| 132 | + (f * 10 ** 8, " 314.1593E+06"), |
| 133 | + (f * 10 ** 9, " 3.1416E+09"), |
| 134 | + (f * 10 ** 10, " 31.4159E+09"), |
| 135 | + (f * 10 ** 11, " 314.1593E+09"), |
| 136 | + (f * 10 ** 12, " 3.1416E+12"), |
| 137 | + (f * 10 ** 13, " 31.4159E+12"), |
| 138 | + (f * 10 ** 14, " 314.1593E+12"), |
| 139 | + (f * 10 ** 15, " 3.1416E+15"), |
| 140 | + (f * 10 ** 16, " 31.4159E+15"), |
| 141 | + (f * 10 ** 17, " 314.1593E+15"), |
| 142 | + (f * 10 ** 18, " 3.1416E+18"), |
| 143 | + (f * 10 ** 19, " 31.4159E+18"), |
| 144 | + (f * 10 ** 20, " 314.1593E+18"), |
| 145 | + (f * 10 ** 21, " 3.1416E+21"), |
| 146 | + (f * 10 ** 22, " 31.4159E+21"), |
| 147 | + (f * 10 ** 23, " 314.1593E+21"), |
| 148 | + (f * 10 ** 24, " 3.1416E+24"), |
| 149 | + (f * 10 ** 25, " 31.4159E+24"), |
| 150 | + (f * 10 ** 26, " 314.1593E+24")] |
| 151 | + self.compare_all(formatter, in_out) |
| 152 | + |
| 153 | + def test_rounding(self): |
| 154 | + formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True) |
| 155 | + in_out = [(5.55555, ' 5.556'), (55.5555, ' 55.556'), |
| 156 | + (555.555, ' 555.555'), (5555.55, ' 5.556k'), |
| 157 | + (55555.5, ' 55.556k'), (555555, ' 555.555k')] |
| 158 | + self.compare_all(formatter, in_out) |
| 159 | + |
| 160 | + formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True) |
| 161 | + in_out = [(5.55555, ' 5.6'), (55.5555, ' 55.6'), (555.555, ' 555.6'), |
| 162 | + (5555.55, ' 5.6k'), (55555.5, ' 55.6k'), (555555, ' 555.6k')] |
| 163 | + self.compare_all(formatter, in_out) |
| 164 | + |
| 165 | + formatter = fmt.EngFormatter(accuracy=0, use_eng_prefix=True) |
| 166 | + in_out = [(5.55555, ' 6'), (55.5555, ' 56'), (555.555, ' 556'), |
| 167 | + (5555.55, ' 6k'), (55555.5, ' 56k'), (555555, ' 556k')] |
| 168 | + self.compare_all(formatter, in_out) |
| 169 | + |
| 170 | + formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True) |
| 171 | + result = formatter(0) |
| 172 | + self.assertEqual(result, u(' 0.000')) |
| 173 | + |
| 174 | + def test_nan(self): |
| 175 | + # Issue #11981 |
| 176 | + |
| 177 | + formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True) |
| 178 | + result = formatter(np.nan) |
| 179 | + self.assertEqual(result, u('NaN')) |
| 180 | + |
| 181 | + df = pd.DataFrame({'a': [1.5, 10.3, 20.5], |
| 182 | + 'b': [50.3, 60.67, 70.12], |
| 183 | + 'c': [100.2, 101.33, 120.33]}) |
| 184 | + pt = df.pivot_table(values='a', index='b', columns='c') |
| 185 | + fmt.set_eng_float_format(accuracy=1) |
| 186 | + result = pt.to_string() |
| 187 | + self.assertTrue('NaN' in result) |
| 188 | + self.reset_display_options() |
| 189 | + |
| 190 | + def test_inf(self): |
| 191 | + # Issue #11981 |
| 192 | + |
| 193 | + formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True) |
| 194 | + result = formatter(np.inf) |
| 195 | + self.assertEqual(result, u('inf')) |
0 commit comments