Как выполнить перенос данных между столбцами в таблицу csv?
Я новичок в написании сценариев. У меня есть таблица (Table1.txt
), и мне нужно создать другую таблицу, в которой есть столбцы таблицы1, расположенные в столбцах и наоборот. Я нашел решения этой проблемы для Perl и SQL, но не для Python.
Я только начал изучать Python два дня назад, так что это насколько я понял:
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])
Это просто воспроизводит столбцы в виде столбцов. Теперь мне хотелось бы написать последнюю строку как writer.writecol([values])
, но кажется, что такой команды нет, и я не нашел другого способа записи строк в виде столбцов.
Ответы
Ответ 1
Решение в целом для транспонирования последовательности итераций: zip (* original_list)
ввод образца:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
программа
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')
выход:
1 6 11
2 7 12
3 8 13
4 9 14
5 10 15
Ответ 2
@Ответ Ашвини - прекрасный. Магия происходит в
zip(*lis)
Позвольте мне объяснить, почему это работает: zip принимает (в простейшем случае) два списка и "zips" их: zip([1,2,3], [4,5,6])
станет [(1,4), (2,5), (3,6)]
. Поэтому, если вы считаете, что внешний список является матрицей, а внутренние кортежи - строками, это транспонирование (т.е. Мы превратили строки в столбцы).
Теперь zip
является функцией произвольной arity, поэтому она может принимать более двух аргументов:
# 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
Проблема, с которой мы сталкиваемся, заключается в том, что в вашем случае мы не знаем, сколько аргументов мы хотим передать в zip
. Но, по крайней мере, мы уже знаем аргументы: они являются элементами lis
! lis
- это список, и каждый элемент этого списка также является списком (соответствующий одной строке чисел в вашем входном файле). *
- это просто способ использования функции Pythons: "Пожалуйста, используйте элементы того, что следует, как ваши аргументы, а не сама вещь!"
Итак,
lis = [[1,2,3], [4,5,6]]
zip(*lis)
точно совпадает с
zip([1,2,3], [4,5,6])
Поздравляем, теперь вы профессионал Python!; -)
Ответ 3
Поскольку мы говорим о столбцах, строках и транспозициях, возможно, стоит упомянуть 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]])
>>> x.T
array([[ 1, 4, 7, 10],
[ 2, 5, 8, 11],
[ 3, 6, 9, 12]])
Ответ 4
Здесь один из способов сделать это, предположим для простоты, что вы просто хотите распечатать объекты в порядке:
# 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]
Поскольку вам нужен массив для перехода на writer.writerow
, вы можете сделать это
for i in range(len(buffer[0])):
writer.writerow([buffer[j][i] for j in range(len(buffer))])
Ответ 5
Просто чтобы построить на @Akavall ответ, если вы хотите прочитать из файла, транспонируйте, а затем снова сохраните, просто выполните:
from numpy import genfromtxt, savetxt
data = genfromtxt('in.txt')
savetxt('out.txt',data.T)
data.T
в третьей строке, где данные переносятся.