Skip to content

Commit 4a5a677

Browse files
adamkleinwesm
authored andcommitted
working on bunch of issues
1 parent edb2409 commit 4a5a677

File tree

6 files changed

+251
-89
lines changed

6 files changed

+251
-89
lines changed

doc/source/io.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ over the string representation of the object. All arguments are optional:
278278

279279
- ``buf`` default None, for example a StringIO object
280280
- ``columns`` default None, which columns to write
281-
- ``colSpace`` default None, number of spaces to write between columns
281+
- ``col_space`` default None, number of spaces to write between columns
282282
- ``na_rep`` default ``NaN``, representation of NA value
283283
- ``formatters`` default None, a dictionary (by column) of functions each of
284284
which takes a single argument and returns a formatted string
@@ -288,6 +288,8 @@ over the string representation of the object. All arguments are optional:
288288
- ``sparsify`` default True, set to False for a DataFrame with a hierarchical
289289
index to print every multiindex key at each row.
290290
- ``index_names`` default True, will print the names of the indices
291+
- ``index`` default True, will print the index (ie, row labels)
292+
- ``header`` default True, will print the column labels
291293

292294
The Series object also has a ``to_string`` method, but with only the ``buf``,
293295
``na_rep``, ``float_format`` arguments. There is also a ``length`` argument

pandas/core/common.py

+39-43
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ def _try_sort(iterable):
360360
except Exception:
361361
return listed
362362

363-
def set_printoptions(precision=None, column_space=None, max_rows=None,
364-
max_columns=None):
363+
def set_printoptions(precision=None, column_space=None, max_rows=None,
364+
max_columns=None, justify='right'):
365365
"""
366366
Alter default behavior of DataFrame.toString
367367
@@ -376,8 +376,11 @@ def set_printoptions(precision=None, column_space=None, max_rows=None,
376376
Either one, or both can be set to 0 (experimental). Pandas will figure
377377
out how big the terminal is and will not display more rows or/and
378378
columns that can fit on it.
379+
justify : string
380+
'right' or 'left' to justify the values of the dataframe using this
381+
alignment
379382
"""
380-
global _float_format, _column_space, _max_rows, _max_columns
383+
global _float_format, _column_space, _max_rows, _max_columns, _justify
381384
if precision is not None:
382385
float_format = '%.' + '%d' % precision + 'g'
383386
_float_format = lambda x: float_format % x
@@ -387,6 +390,8 @@ def set_printoptions(precision=None, column_space=None, max_rows=None,
387390
_max_rows = max_rows
388391
if max_columns is not None:
389392
_max_columns = max_columns
393+
if justify is not None and justify in ('right', 'left'):
394+
_justify = justify
390395

391396
class EngFormatter(object):
392397
"""
@@ -491,33 +496,11 @@ def set_eng_float_format(precision=3, use_eng_prefix=False):
491496
_float_format = EngFormatter(precision, use_eng_prefix)
492497
_column_space = max(12, precision + 9)
493498

494-
_float_format = lambda x: '%.4g' % x
499+
_float_format = lambda x: '% .4f' % x
495500
_column_space = 12
496501
_max_rows = 500
497502
_max_columns = 0
498-
499-
def _pfixed(s, space, na_rep=None, float_format=None):
500-
if isinstance(s, float):
501-
if na_rep is not None and isnull(s):
502-
if np.isnan(s):
503-
s = na_rep
504-
return (' %s' % s).ljust(space)
505-
506-
if float_format:
507-
formatted = float_format(s)
508-
else:
509-
is_neg = s < 0
510-
formatted = _float_format(np.abs(s))
511-
512-
if is_neg:
513-
formatted = '-' + formatted
514-
else:
515-
formatted = ' ' + formatted
516-
517-
return formatted.ljust(space)
518-
else:
519-
stringified = _stringify(s)
520-
return (' %s' % stringified)[:space].ljust(space)
503+
_justify = 'right'
521504

522505
def _stringify(col):
523506
# unicode workaround
@@ -526,29 +509,31 @@ def _stringify(col):
526509
else:
527510
return '%s' % col
528511

529-
def _format(s, na_rep=None, float_format=None):
512+
def _format(s, space=None, na_rep=None, float_format=None):
513+
def _just_help(x):
514+
if space is None:
515+
return x
516+
if _justify == 'right':
517+
return x[:space].rjust(space)
518+
else:
519+
return x[:space].ljust(space)
520+
530521
if isinstance(s, float):
531522
if na_rep is not None and isnull(s):
532523
if np.isnan(s):
533524
s = na_rep
534-
return ' %s' % s
525+
return _just_help('%s' % s)
535526

536527
if float_format:
537528
formatted = float_format(s)
538529
else:
539-
is_neg = s < 0
540-
formatted = _float_format(np.abs(s))
541-
542-
if is_neg:
543-
formatted = '-' + formatted
544-
else:
545-
formatted = ' ' + formatted
530+
formatted = _float_format(s)
546531

547-
return formatted
532+
return _just_help(formatted)
548533
else:
549-
return ' %s' % _stringify(s)
534+
return _just_help('%s' % _stringify(s))
550535

551-
#-------------------------------------------------------------------------------
536+
#------------------------------------------------------------------------------
552537
# miscellaneous python tools
553538

554539
def rands(n):
@@ -564,14 +549,22 @@ def adjoin(space, *lists):
564549
"""
565550
outLines = []
566551
newLists = []
567-
lengths = [max(map(len, x)) + space for x in lists[:-1]]
568552

569-
# not the last one
570-
lengths.append(max(map(len, lists[-1])))
553+
if _justify == 'right':
554+
# everyone but the first one, add space (right-aligned)
555+
lengths = [max(map(len, x)) + space for x in lists[1:]]
556+
lengths.insert(0, max(map(len, lists[0])))
557+
else:
558+
# everyone but the last one, add space (left-aligned)
559+
lengths = [max(map(len, x)) + space for x in lists[:-1]]
560+
lengths.append(max(map(len, lists[-1])))
571561

572562
maxLen = max(map(len, lists))
573563
for i, lst in enumerate(lists):
574-
nl = [x.ljust(lengths[i]) for x in lst]
564+
if _justify == 'right':
565+
nl = [x.rjust(lengths[i]) for x in lst]
566+
else:
567+
nl = [x.ljust(lengths[i]) for x in lst]
575568
nl.extend([' ' * lengths[i]] * (maxLen - len(lst)))
576569
newLists.append(nl)
577570
toJoin = zip(*newLists)
@@ -691,6 +684,9 @@ def is_integer_dtype(arr):
691684
def is_float_dtype(arr):
692685
return issubclass(arr.dtype.type, np.floating)
693686

687+
def is_numeric_dtype(arr):
688+
return is_integer_dtype(arr) or is_float_dtype(arr)
689+
694690
def save(obj, path):
695691
"""
696692
Pickle (serialize) object to input file path

pandas/core/format.py

+79-31
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,50 @@
11
from StringIO import StringIO
2-
from pandas.core.common import adjoin, _pfixed
2+
from pandas.core.common import adjoin, is_numeric_dtype
33
from pandas.core.index import MultiIndex, _ensure_index
44

5+
docstring_to_string = """
6+
Parameters
7+
----------
8+
frame : DataFrame
9+
object to render
10+
buf : StringIO-like, optional
11+
buffer to write to
12+
columns : sequence, optional
13+
the subset of columns to write; default None writes all columns
14+
col_space : int, optional
15+
the width of each columns
16+
header : bool, optional
17+
whether to print column labels, default True
18+
index : bool, optional
19+
whether to print index (row) labels, default True
20+
na_rep : string, optional
21+
string representation of NAN to use, default 'NaN'
22+
formatters : list or dict of one-parameter functions, optional
23+
formatter functions to apply to columns' elements by position or name,
24+
default None
25+
float_format : one-parameter function, optional
26+
formatter function to apply to columns' elements if they are floats
27+
default None
28+
sparsify : bool, optional
29+
Set to False for a DataFrame with a hierarchical index to print every
30+
multiindex key at each row, default True
31+
index_names : bool, optional
32+
Prints the names of the indexes, default True """
533

634
class DataFrameFormatter(object):
735
"""
836
Render a DataFrame
937
1038
self.to_string() : console-friendly tabular output
11-
self.to_html() : html table
39+
self.to_html() : html table
40+
1241
"""
13-
def __init__(self, frame, buf=None, columns=None, col_space=None,
14-
na_rep='NaN', formatters=None, float_format=None,
15-
sparsify=True, index_names=True):
1642

43+
__doc__ += docstring_to_string
44+
45+
def __init__(self, frame, buf=None, columns=None, col_space=None,
46+
header=True, index=True, na_rep='NaN', formatters=None,
47+
float_format=None, sparsify=True, index_names=True):
1748
self.frame = frame
1849
self.buf = buf if buf is not None else StringIO()
1950
self.show_index_names = index_names
@@ -22,6 +53,8 @@ def __init__(self, frame, buf=None, columns=None, col_space=None,
2253
self.formatters = formatters
2354
self.na_rep = na_rep
2455
self.col_space = col_space
56+
self.header = header
57+
self.index = index
2558

2659
if columns is not None:
2760
self.columns = _ensure_index(columns)
@@ -47,10 +80,16 @@ def to_string(self):
4780
str_index = self._get_formatted_index()
4881
str_columns = self._get_formatted_column_labels()
4982

50-
stringified = [str_columns[i] + format_col(c)
51-
for i, c in enumerate(self.columns)]
83+
if self.header:
84+
stringified = [str_columns[i] + format_col(c)
85+
for i, c in enumerate(self.columns)]
86+
else:
87+
stringified = [format_col(c) for c in self.columns]
5288

53-
to_write.append(adjoin(1, str_index, *stringified))
89+
if self.index:
90+
to_write.append(adjoin(1, str_index, *stringified))
91+
else:
92+
to_write.append(adjoin(1, *stringified))
5493

5594
for s in to_write:
5695
if isinstance(s, unicode):
@@ -114,17 +153,21 @@ def _column_header():
114153
write(buf, '</tbody>', indent + indent_delta)
115154
else:
116155
indent += indent_delta
117-
write(buf, '<thead>', indent)
118-
row = []
119156

120157
# header row
121-
col_row = _column_header()
122-
indent += indent_delta
123-
write_tr(buf, col_row, indent, indent_delta, header=True)
124-
if self.has_index_names:
125-
row = frame.index.names + [''] * len(frame.columns)
126-
write_tr(buf, row, indent, indent_delta, header=True)
127-
write(buf, '</thead>', indent)
158+
if self.header:
159+
write(buf, '<thead>', indent)
160+
row = []
161+
162+
col_row = _column_header()
163+
indent += indent_delta
164+
write_tr(buf, col_row, indent, indent_delta, header=True)
165+
if self.has_index_names:
166+
row = frame.index.names + [''] * len(frame.columns)
167+
write_tr(buf, row, indent, indent_delta, header=True)
168+
169+
write(buf, '</thead>', indent)
170+
128171
write(buf, '<tbody>', indent)
129172

130173
# write values
@@ -148,14 +191,9 @@ def _get_column_formatter(self):
148191

149192
col_space = self.col_space
150193

151-
if col_space is None:
152-
def _myformat(v):
153-
return _format(v, na_rep=self.na_rep,
154-
float_format=self.float_format)
155-
else:
156-
def _myformat(v):
157-
return _pfixed(v, col_space, na_rep=self.na_rep,
158-
float_format=self.float_format)
194+
def _myformat(v):
195+
return _format(v, space=col_space, na_rep=self.na_rep,
196+
float_format=self.float_format)
159197

160198
formatters = {} if self.formatters is None else self.formatters
161199

@@ -171,16 +209,24 @@ def _format_col(col, i=None):
171209
def _get_formatted_column_labels(self):
172210
from pandas.core.index import _sparsify
173211

212+
formatters = self.formatters
213+
if formatters is None:
214+
formatters = {}
215+
174216
if isinstance(self.columns, MultiIndex):
175217
fmt_columns = self.columns.format(sparsify=False, adjoin=False)
176-
str_columns = zip(*[[' %s' % y for y in x]
218+
str_columns = zip(*[[' %s' % y if y not in formatters and is_numeric_dtype(self.frame[x])
219+
else str(y)
220+
for y in x]
177221
for x in zip(*fmt_columns)])
178222
if self.sparsify:
179223
str_columns = _sparsify(str_columns)
180224

181225
str_columns = [list(x) for x in zip(*str_columns)]
182226
else:
183-
str_columns = [[' %s' % x] for x in self.columns.format()]
227+
str_columns = [[' %s' % x if x not in formatters and is_numeric_dtype(self.frame[x])
228+
else str(x)]
229+
for x in self.columns.format()]
184230

185231
if self.show_index_names and self.has_index_names:
186232
for x in str_columns:
@@ -201,7 +247,7 @@ def _get_formatted_index(self):
201247
columns = self.frame.columns
202248

203249
show_index_names = self.show_index_names and self.has_index_names
204-
show_col_names = self.show_index_names and self.has_column_names
250+
show_col_names = (self.show_index_names and self.has_column_names)
205251

206252
if isinstance(index, MultiIndex):
207253
fmt_index = index.format(sparsify=self.sparsify, adjoin=False,
@@ -213,11 +259,14 @@ def _get_formatted_index(self):
213259

214260
# empty space for columns
215261
if show_col_names:
216-
col_header = [' %s' % x for x in self._get_column_name_list()]
262+
col_header = ['%s' % x for x in self._get_column_name_list()]
217263
else:
218264
col_header = [''] * columns.nlevels
219265

220-
return col_header + adjoined
266+
if self.header:
267+
return col_header + adjoined
268+
else:
269+
return adjoined
221270

222271
def _get_column_name_list(self):
223272
names = []
@@ -229,7 +278,6 @@ def _get_column_name_list(self):
229278
names.append('' if columns.name is None else columns.name)
230279
return names
231280

232-
233281
def single_column_table(column):
234282
table = '<table><tbody>'
235283
for i in column:

0 commit comments

Comments
 (0)