¿Cómo hacer la transposición fila a columna de datos en la tabla csv?

Soy nuevo en scripting. Tengo una tabla ( Table1.txt ) y necesito crear otra tabla que tenga las filas de Table1 organizadas en columnas y viceversa. He encontrado soluciones a este problema para Perl y SQL pero no para Python.

Acabo de comenzar a aprender Python hace dos días, así que esto es lo que tengo:

 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]) 

Esto solo reproduce las columnas como columnas. Lo que me hubiera gustado hacer ahora es escribir la última línea como writer.writecol([values]) pero parece que no hay un comando así y no he encontrado otra forma de escribir filas como columnas.

La solución en general para transponer una secuencia de iterables es: zip (* original_list)

muestra de entrada:

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

progtwig:

 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') 

salida:

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

La respuesta de @ Ashwini es perfecta. La magia pasa en

 zip(*lis) 

Permítanme explicar por qué funciona esto: zip toma (en el caso más simple) dos listas y las “comprime”: zip([1,2,3], [4,5,6]) se convertirá en [(1,4), (2,5), (3,6)] . Entonces, si considera que la lista externa es una matriz y las tuplas internas son las filas, eso es una transposición (es decir, convertimos las filas en columnas).

Ahora, zip es una función de aridad arbitraria, por lo que puede tomar más de dos argumentos:

 # 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 

El problema al que nos enfrentamos es que, en su caso, no sabemos cuántos argumentos queremos pasar a zip . Pero al menos, ya conocemos los argumentos: ¡son los elementos de lis ! lis es una lista, y cada elemento de esa lista también es una lista (que corresponde a una línea de números en su archivo de entrada). La * es solo la forma en que los Pythons le dicen a una función “¡por favor usa los elementos de lo que sigue como tus argumentos y no la cosa en sí!”

Asi que

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

es exactamente lo mismo que

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

¡Felicidades, ahora eres un profesional de Python! 😉

Ya que estamos hablando de columnas, filas y transpuestos, tal vez valga la pena mencionar numpy

 >>> import numpy as np >>> x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) >>> x array([[ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 9], [10, 11, 12]]) >>> xT array([[ 1, 4, 7, 10], [ 2, 5, 8, 11], [ 3, 6, 9, 12]]) 

Aquí hay una forma de hacerlo, suponga que, para simplificar, solo desea imprimir los objetos en orden:

  # lets read all the data into a big 2d array buffer = [] for row in readinput: values = [row[0], row[1], row[2], row[3]] buffer.append(values) # what you have in your code for i in range(len(buffer)): for j in range(len(buffer[0])): print buffer[i][j] # this is called a transpose; we have buffer[i][j] to read row then column, # switch i and j around to do the opposite for i in range(len(buffer[0])): for j in range(len(buffer)): print buffer[j][i] 

Ya que necesitas una matriz para pasar a writer.writerow , puedes hacer esto

  for i in range(len(buffer[0])): writer.writerow([buffer[j][i] for j in range(len(buffer))]) 

Solo para construir en la respuesta @Akavall, si desea leer un archivo, transponga y luego vuelva a guardar, solo haga lo siguiente:

 from numpy import genfromtxt, savetxt data = genfromtxt('in.txt') savetxt('out.txt',data.T) 

data.T en la tercera línea es donde se transponen los datos.