4
4
# pylint: disable=W0141
5
5
6
6
import sys
7
- import re
8
7
9
8
from pandas .core .base import PandasObject
10
- from pandas .core .common import adjoin , isnull , notnull
9
+ from pandas .core .common import adjoin , notnull
11
10
from pandas .core .index import Index , MultiIndex , _ensure_index
12
11
from pandas import compat
13
12
from pandas .compat import (StringIO , lzip , range , map , zip , reduce , u ,
14
13
OrderedDict )
15
14
from pandas .util .terminal import get_terminal_size
16
- from pandas .core .config import get_option , set_option , reset_option
15
+ from pandas .core .config import get_option , set_option
17
16
import pandas .core .common as com
18
17
import pandas .lib as lib
19
18
from pandas .tslib import iNaT
22
21
23
22
import itertools
24
23
import csv
25
- from datetime import time
26
24
27
25
from pandas .tseries .period import PeriodIndex , DatetimeIndex
28
26
@@ -321,30 +319,69 @@ def __init__(self, frame, buf=None, columns=None, col_space=None,
321
319
self ._chk_truncate ()
322
320
323
321
def _chk_truncate (self ):
322
+ '''
323
+ Checks whether the frame should be truncated. If so, slices
324
+ the frame up.
325
+ '''
324
326
from pandas .tools .merge import concat
325
327
326
- truncate_h = self . max_cols and ( len ( self . columns ) > self . max_cols )
327
- truncate_v = self .max_rows and ( len ( self . frame ) > self . max_rows )
328
+ # Column of which first element is used to determine width of a dot col
329
+ self .tr_size_col = - 1
328
330
329
331
# Cut the data to the information actually printed
330
332
max_cols = self .max_cols
331
333
max_rows = self .max_rows
334
+
335
+ if max_cols == 0 or max_rows == 0 : # assume we are in the terminal (why else = 0)
336
+ (w ,h ) = get_terminal_size ()
337
+ self .w = w
338
+ self .h = h
339
+ if self .max_rows == 0 :
340
+ dot_row = 1
341
+ prompt_row = 1
342
+ if self .show_dimensions :
343
+ show_dimension_rows = 3
344
+ n_add_rows = self .header + dot_row + show_dimension_rows + prompt_row
345
+ max_rows_adj = self .h - n_add_rows # rows available to fill with actual data
346
+ self .max_rows_adj = max_rows_adj
347
+
348
+ # Format only rows and columns that could potentially fit the screen
349
+ if max_cols == 0 and len (self .frame .columns ) > w :
350
+ max_cols = w
351
+ if max_rows == 0 and len (self .frame ) > h :
352
+ max_rows = h
353
+
354
+ if not hasattr (self ,'max_rows_adj' ):
355
+ self .max_rows_adj = max_rows
356
+ if not hasattr (self ,'max_cols_adj' ):
357
+ self .max_cols_adj = max_cols
358
+
359
+ max_cols_adj = self .max_cols_adj
360
+ max_rows_adj = self .max_rows_adj
361
+
362
+ truncate_h = max_cols_adj and (len (self .columns ) > max_cols_adj )
363
+ truncate_v = max_rows_adj and (len (self .frame ) > max_rows_adj )
364
+
332
365
frame = self .frame
333
366
if truncate_h :
334
- if max_cols > 1 :
335
- col_num = (max_cols // 2 )
336
- frame = concat ( (frame .iloc [:,:col_num ],frame .iloc [:,- col_num :]),axis = 1 )
337
- else :
338
- col_num = max_cols
367
+ if max_cols_adj == 0 :
368
+ col_num = len (frame .columns )
369
+ elif max_cols_adj == 1 :
339
370
frame = frame .iloc [:,:max_cols ]
371
+ col_num = max_cols
372
+ else :
373
+ col_num = (max_cols_adj // 2 )
374
+ frame = concat ( (frame .iloc [:,:col_num ],frame .iloc [:,- col_num :]),axis = 1 )
340
375
self .tr_col_num = col_num
341
376
if truncate_v :
342
- if max_rows > 1 :
343
- row_num = max_rows // 2
344
- frame = concat ( (frame .iloc [:row_num ,:],frame .iloc [- row_num :,:]) )
345
- else :
377
+ if max_rows_adj == 0 :
378
+ row_num = len (frame )
379
+ if max_rows_adj == 1 :
346
380
row_num = max_rows
347
381
frame = frame .iloc [:max_rows ,:]
382
+ else :
383
+ row_num = max_rows_adj // 2
384
+ frame = concat ( (frame .iloc [:row_num ,:],frame .iloc [- row_num :,:]) )
348
385
self .tr_row_num = row_num
349
386
350
387
self .tr_frame = frame
@@ -360,13 +397,12 @@ def _to_str_columns(self):
360
397
frame = self .tr_frame
361
398
362
399
# may include levels names also
363
- str_index = self ._get_formatted_index (frame )
364
400
401
+ str_index = self ._get_formatted_index (frame )
365
402
str_columns = self ._get_formatted_column_labels (frame )
366
403
367
404
if self .header :
368
405
stringified = []
369
- col_headers = frame .columns
370
406
for i , c in enumerate (frame ):
371
407
cheader = str_columns [i ]
372
408
max_colwidth = max (self .col_space or 0 ,
@@ -389,7 +425,6 @@ def _to_str_columns(self):
389
425
else :
390
426
stringified = []
391
427
for i , c in enumerate (frame ):
392
- formatter = self ._get_formatter (i )
393
428
fmt_values = self ._format_col (i )
394
429
fmt_values = _make_fixed_width (fmt_values , self .justify ,
395
430
minimum = (self .col_space or 0 ))
@@ -406,8 +441,8 @@ def _to_str_columns(self):
406
441
407
442
if truncate_h :
408
443
col_num = self .tr_col_num
409
- col_width = len (strcols [col_num ][0 ]) # infer from column header
410
- strcols .insert (col_num + 1 , ['...' .center (col_width )] * (len (str_index )))
444
+ col_width = len (strcols [self . tr_size_col ][0 ]) # infer from column header
445
+ strcols .insert (self . tr_col_num + 1 , ['...' .center (col_width )] * (len (str_index )))
411
446
if truncate_v :
412
447
n_header_rows = len (str_index ) - len (frame )
413
448
row_num = self .tr_row_num
@@ -424,19 +459,19 @@ def _to_str_columns(self):
424
459
if ix == 0 :
425
460
dot_str = my_str .ljust (cwidth )
426
461
elif is_dot_col :
462
+ cwidth = len (strcols [self .tr_size_col ][0 ])
427
463
dot_str = my_str .center (cwidth )
428
464
else :
429
465
dot_str = my_str .rjust (cwidth )
430
466
431
467
strcols [ix ].insert (row_num + n_header_rows , dot_str )
432
-
433
468
return strcols
434
469
435
470
def to_string (self ):
436
471
"""
437
472
Render a DataFrame to a console-friendly tabular output.
438
473
"""
439
-
474
+ from pandas import Series
440
475
frame = self .frame
441
476
442
477
if len (frame .columns ) == 0 or len (frame .index ) == 0 :
@@ -447,10 +482,40 @@ def to_string(self):
447
482
text = info_line
448
483
else :
449
484
strcols = self ._to_str_columns ()
450
- if self .line_width is None :
485
+ if self .line_width is None : # no need to wrap around just print the whole frame
451
486
text = adjoin (1 , * strcols )
452
- else :
487
+ elif not isinstance ( self . max_cols , int ) or self . max_cols > 0 : # perhaps need to wrap around
453
488
text = self ._join_multiline (* strcols )
489
+ else : # max_cols == 0. Try to fit frame to terminal
490
+ text = adjoin (1 , * strcols ).split ('\n ' )
491
+ row_lens = Series (text ).apply (len )
492
+ max_len_col_ix = np .argmax (row_lens )
493
+ max_len = row_lens [max_len_col_ix ]
494
+ headers = [ele [0 ] for ele in strcols ]
495
+ # Size of last col determines dot col size. See `self._to_str_columns
496
+ size_tr_col = len (headers [self .tr_size_col ])
497
+ max_len += size_tr_col # Need to make space for largest row plus truncate (dot) col
498
+ dif = max_len - self .w
499
+ adj_dif = dif
500
+ col_lens = Series ([Series (ele ).apply (len ).max () for ele in strcols ])
501
+ n_cols = len (col_lens )
502
+ counter = 0
503
+ while adj_dif > 0 and n_cols > 1 :
504
+ counter += 1
505
+ mid = int (round (n_cols / 2. ))
506
+ mid_ix = col_lens .index [mid ]
507
+ col_len = col_lens [mid_ix ]
508
+ adj_dif -= ( col_len + 1 ) # adjoin adds one
509
+ col_lens = col_lens .drop (mid_ix )
510
+ n_cols = len (col_lens )
511
+ max_cols_adj = n_cols - self .index # subtract index column
512
+ self .max_cols_adj = max_cols_adj
513
+
514
+ # Call again _chk_truncate to cut frame appropriately
515
+ # and then generate string representation
516
+ self ._chk_truncate ()
517
+ strcols = self ._to_str_columns ()
518
+ text = adjoin (1 , * strcols )
454
519
455
520
self .buf .writelines (text )
456
521
@@ -472,8 +537,8 @@ def _join_multiline(self, *strcols):
472
537
col_bins = _binify (col_widths , lwidth )
473
538
nbins = len (col_bins )
474
539
475
- if self .max_rows and len ( self . frame ) > self . max_rows :
476
- nrows = self .max_rows + 1
540
+ if self .truncate_v :
541
+ nrows = self .max_rows_adj + 1
477
542
else :
478
543
nrows = len (self .frame )
479
544
@@ -636,6 +701,7 @@ def is_numeric_dtype(dtype):
636
701
for x in str_columns :
637
702
x .append ('' )
638
703
704
+ # self.str_columns = str_columns
639
705
return str_columns
640
706
641
707
@property
0 commit comments