Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do row-to-column transposition of data in csv table?

Tags:

python

csv

I'm new to scripting. I have a table (Table1.txt) and I need to create another table that has Table1's rows arranged in columns and vice versa. I have found solutions to this problem for Perl and SQL but not for Python.

I just started learning Python two days ago, so this is as far as I got:

import csv import sys  with open(sys.argv[1], "rt") as inputfile:    readinput = csv.reader(inputfile, delimiter='\t')    with open("output.csv", 'wt') as outputfile:       writer = csv.writer(outputfile, delimiter="\t")       for row in readinput:             values = [row[0], row[1], row[2], row[3]]             writer.writerow([values]) 

This just reproduces the columns as columns. What I would have liked to do now is to write the last line as writer.writecol([values]) but it seems that there is no command like that and I haven't found another way of writing rows as columns.

like image 285
Frank Avatar asked May 08 '12 21:05

Frank


People also ask

How do I convert a row to a column in a table?

Right-click on a cell where you want to convert rows to columns. Select the Paste Transpose option to rotate rows to columns.

How do you transpose data in a row?

Highlight the area you want to transpose and then press Ctrl + C on the keyboard to copy the data. Right-click the empty cell where you'd like to display your results. Under “Paste Options” click “Paste Special.”


2 Answers

@Ashwini's answer is perfect. The magic happens in

zip(*lis) 

Let me explain why this works: zip takes (in the simplest case) two lists and "zips" them: zip([1,2,3], [4,5,6]) will become [(1,4), (2,5), (3,6)]. So if you consider the outer list to be a matrix and the inner tuples to be the rows, that's a transposition (ie., we turned the rows to columns).

Now, zip is a function of arbitrary arity, so it can take more then two arguments:

# Our matrix is: # 1 2 3 # 4 5 6 # 7 8 9  zip([1,2,3], [4,5,6], [7,8,9])  >>> [(1, 4, 7), (2, 5, 8), (3, 6, 9)]  # Now it is # 1 4 7 # 2 5 8 # 3 6 9 

The problem we're facing is that in your case, we don't know how many arguments we want to pass to zip. But at least, we already know the arguments: they are the elements of lis! lis is a list, and each element of that list is a list as well (corresponding to one line of numbers in your input file). The * is just Pythons way of telling a function "please use the elements of whatever follows as your arguments and not the thing itself!"

So

lis = [[1,2,3], [4,5,6]] zip(*lis) 

is exactly the same as

zip([1,2,3], [4,5,6]) 

Congrats, now you're a Python pro! ;-)

like image 151
Manuel Ebert Avatar answered Sep 19 '22 18:09

Manuel Ebert


The solution in general to transpose a sequence of iterables is: zip(*original_list)

sample input:

1   2   3   4   5 6   7   8   9   10 11  12  13  14  15 

program:

with open('in.txt') as f:   lis = [x.split() for x in f]  for x in zip(*lis):   for y in x:     print(y+'\t', end='')   print('\n') 

output:

1   6   11    2   7   12    3   8   13    4   9   14    5   10  15 
like image 43
Ashwini Chaudhary Avatar answered Sep 16 '22 18:09

Ashwini Chaudhary