Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to columnate a list in python?

I have a pandas Series, sufficiently small so I can read all items (about 80), but too big for the size of the screen.

Is there some python command ou ipython (notebook) magic command or pandas function to columnate that list or Series so I can read it entirely without scrolling down and up?

I'm basically looking for the equivalent of the column command in bash.

For example, I have a Series like this:

A      76
B      56
C      42
D      31
E      31
F      25
G      24

And let's say that my screen is so small that I need to scroll down to see after the B row. What I'd like is something like this:

A    76        C    42        E    31        G    24
B    56        D    31        F    25
like image 551
jrjc Avatar asked Aug 23 '26 20:08

jrjc


2 Answers

The following non-numpy/pandas solution might give you some inspiration:

import itertools

rows =  [("A", 76),  ("B", 56), ("C", 42), ("D", 31), ("E", 31), ("F", 25), ("G", 24)]

def print_multi_cols(lrows, split_at=5, space_each=4):
    for row in itertools.izip(*itertools.izip_longest(*[iter(lrows)]*split_at, fillvalue=(" ", " "))):
        for col in row:
            print " ".join(["%-*s" % (space_each, item) for item in col]),
        print

print_multi_cols(rows, 2)
print_multi_cols(rows, 3)

This gives the following output:

A     76      C     42      E     31      G     24     
B     56      D     31      F     25                   

A     76      D     31      G     24     
B     56      E     31                   
C     42      F     25

You would need to convert your series before this could be used. Tested using Python 2.7.

Or for a bit more control over the justification, it could be modified as follows:

import itertools

rows =  [("A", 9),  ("B", 56), ("C", 42), ("D", 31), ("E", 31), ("F", 25), ("G", 999)]

def print_multi_cols(lrows, split_at=5, space_each=4, left_justify=None):
    if not left_justify:
        left_justify = [True] * len(lrows[0])

    for row in itertools.izip(*itertools.izip_longest(*[iter(lrows)]*split_at, fillvalue=(" ", " "))):
        for col in row:
            print " ".join([("%-*s " if left else "%*s ") % (space_each, item) for item, left in itertools.izip(col, left_justify)]),
        print
    print

print_multi_cols(rows, split_at=5, space_each=3, left_justify=[True, False])

Giving:

A      9  F     25 
B     56  G    999 
C     42           
D     31           
E     31
like image 196
Martin Evans Avatar answered Aug 26 '26 11:08

Martin Evans


Using the idea of a show function (with some loops, but since data that can be shown that way is small, it should be fine).

def show(series, cols=6):                                                        
    rows = int(np.ceil(len(series)/float(cols)))                                 
    indices = series.index                                                       

    ind_loop = 0                                                                 
    for row in range(rows):                                                      
        ind = indices[ind_loop:ind_loop+cols]                                    
        dat = series[ind]                                                        
        comb = zip(ind, dat)                                                     
        print_str = ""                                                           
        for num in range(len(dat)):                                              
            print_str += "{{{0}: <10}} ".format(num)                             

        print(print_str.format(*comb))                                           
        ind_loop += cols                                                         

ser = pd.Series(range(20))                                                                                                                                                        
show(ser, cols=6) 

(0, 0)     (1, 1)     (2, 2)     (3, 3)     (4, 4)     (5, 5)                     
(6, 6)     (7, 7)     (8, 8)     (9, 9)     (10, 10)   (11, 11)
(12, 12)   (13, 13)   (14, 14)   (15, 15)   (16, 16)   (17, 17)
(18, 18)   (19, 19)

You could adjust the print to show something like index : value if you like.

like image 38
chris-sc Avatar answered Aug 26 '26 10:08

chris-sc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!