我有一堆 CSV 文件(下例中只有两个)。每个 CSV 文件有 6 列。我想进入每个 CSV 文件,复制前两列并将它们作为新列添加到现有的 CSV 文件中。
到目前为止我有:
import csv
f = open('combined.csv')
data = [item for item in csv.reader(f)]
f.close()
for x in range(1,3): #example has 2 csv files, this will be automated
n=0
while n<2:
f=open(str(x)+".csv")
new_column=[item[n] for item in csv.reader(f)]
f.close()
#print d
new_data = []
for i, item in enumerate(data):
try:
item.append(new_column[i])
print i
except IndexError, e:
item.append("")
new_data.append(item)
f = open('combined.csv', 'w')
csv.writer(f).writerows(new_data)
f.close()
n=n+1
这行得通,虽然不漂亮,但行得通。 但是,我有三个小烦恼:
我打开每个 CSV 文件两次(每列一次),这很难说
当我打印
combined.csv
文件时,它会在每一行之后打印一个空行吗?我必须提供一个
combined.csv
文件,其中的行数至少与我可能拥有的最大文件一样多。因为我真的不知道那个数字可能是多少,所以有点糟糕
一如既往,非常感谢任何帮助!!
根据要求: 1.csv看起来像(模拟数据)
1,a
2,b
3,c
4,d
2.csv的样子
5,e
6,f
7,g
8,h
9,i
combined.csv 文件应该是这样的
1,a,5,e
2,b,6,f
3,c,7,g
4,d,8,h
,,9,i
最佳答案
import csv
import itertools as IT
filenames = ['1.csv', '2.csv']
handles = [open(filename, 'rb') for filename in filenames]
readers = [csv.reader(f, delimiter=',') for f in handles]
with open('combined.csv', 'wb') as h:
writer = csv.writer(h, delimiter=',', lineterminator='\n', )
for rows in IT.izip_longest(*readers, fillvalue=['']*2):
combined_row = []
for row in rows:
row = row[:2] # select the columns you want
if len(row) == 2:
combined_row.extend(row)
else:
combined_row.extend(['']*2)#This extends two empty columns
writer.writerow(combined_row)
for f in handles:
f.close()
行 for rows in IT.izip_longest(*readers, fillvalue=['']*2):
可以通过一个例子来理解:
In [1]: import itertools as IT
In [2]: readers = [(1,2,3), ('a','b','c','d'), (10,20,30,40)]
In [3]: list(IT.izip_longest(readers[0], readers[1], readers[2]))
Out[3]: [(1, 'a', 10), (2, 'b', 20), (3, 'c', 30), (None, 'd', 40)]
如您所见,IT.izip_longest行为非常像 zip
,除了它不会停止直到最长的迭代被消耗。默认情况下,它用 None
填充缺失的项目。
现在,如果 readers
中的项目超过 3 个会怎样?
我们想写
list(IT.izip_longest(readers[0], readers[1], readers[2], ...))
但这很费力,如果我们事先不知道 len(readers)
,我们甚至无法将省略号 (...
) 替换为一些明确的东西。
Python 对此有一个解决方案:the star (aka argument unpacking) syntax :
In [4]: list(IT.izip_longest(*readers))
Out[4]: [(1, 'a', 10), (2, 'b', 20), (3, 'c', 30), (None, 'd', 40)]
注意结果 Out[4]
与结果 Out[3]
相同。
*readers
告诉 Python 解压 readers
中的项目,并将它们作为单独的参数发送给 IT.izip_longest
。
这就是 Python 允许我们向函数发送任意数量的参数的方式。
关于python - 将多个 CSV 文件中的列合并到一个文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14530748/