我有一组csv文件,其名称为2.csv
,3.csv
....,999.csv
。每个文件中都有91行。我想要一组新文件从所有文件中收集特定行。例如。 row1.csv
应该包含所有998个文件的第一行,类似地,row35.csv应该包含所有998个文件的第35行。因此,在我的脚本完成运行后,我应该总共有91个文件(每行一个),每个文件有998行(每个原始文件一行)。
我使用以下代码执行任务
import glob
import os
for i in range(2,92):
outfile = open("row_%i.csv" %i,'w')
for filename in glob.glob('DataSet-MediaEval/devFeatures/*.csv'):
with open(filename, 'r') as infile:
lineno = 0
for line in infile:
lineno += 1
if lineno == i:
outfile.write(line)
outfile.close()
现在在任何outfile row_i.csv
中,我的数据按字典排序顺序排列。示例:
row_50.csv
文件中的第一行是10.csv
的第50行。
换句话说,在任何row_i.csv
中,行都来自10.csv
,100.csv
,101.csv,依此类推。
我想知道为什么会发生这种情况,并且有一种方法可以确保我的r ow_i.csv
按照文件的顺序进行排序,即2.csv
,3.csv
等等。
感谢您花时间阅读本文。
答案 0 :(得分:2)
不确定这是否成功或是否存在更多问题,但似乎glob
要么按排序顺序返回文件名(按字符串排序),要么按随机顺序返回。在这两种情况下,您都必须从文件名中提取数字并按该数字排序。
尝试这样的事情:
p = re.compile(r"/(\d+)\.csv")
filenames = glob.glob(...)
for filename in sorted(filenames, key=lambda s: int(re.search(p, s).group(1))):
...
此外,您似乎一次又一次地打开,循环并关闭所有92个文件的所有999个文件!最好一次打开所有92个outfiles并将它们存储在字典中,将行号映射到文件。这样,您只需要循环999个文件。
这样的事情(完全未经测试):
outfiles = {i: open("row_%i.csv" %i, 'w') for i in range(2,92)}
p = re.compile(r"/(\d+)\.csv")
filenames = glob.glob('DataSet-MediaEval/devFeatures/*.csv'):
for filename in sorted(filenames, key=lambda s: int(re.search(p, s).group(1))):
with open(filename, 'r') as infile:
for lineno, line in enumerate(infile):
outfiles[lineno].write(line)
for outfile in outfiles.values():
outfile.close()
答案 1 :(得分:0)
您需要在开始迭代之前对文件名列表进行排序。这可以帮到你:
import re
import glob
filename_list = glob.glob('DataSet-MediaEval/devFeatures/*.csv')
def splitByNumbers(x):
r = re.compile('(\d+)')
l = r.split(x)
return [int(y) if y.isdigit() else y for y in l]
filenames = sorted(filename_list, key = splitByNumbers)
然后你可以用而不是
for filename in glob.glob('DataSet-MediaEval/devFeatures/*.csv'):
此
for filename in filenames: