从多个csv文件中提取行和文件名

时间:2011-11-04 23:41:38

标签: python

我在文件夹中有多个日期为文件名(20080101.csv到20111031.csv)的csv文件。 csv文件有共同的标题。 csv文件如下所示:

20080101.csv  
X ;Y; Z  
1 ; 1 ; 3  
1 ; 2 ; 6  
1 ; 3 ; 24  
2 ; 1 ; 24  
2 ; 2 ; 24  

20080102.csv   
X ;Y; Z  
1 ; 1 ; 0.1  
1 ; 2 ; 2  
1 ; 3 ; 67  
2 ; 1 ; 24  
2 ; 2 ; 24  

20080103.csv  
X ;Y; Z  
1 ; 1 ; 3  
1 ; 3 ; 24  
2 ; 1 ; 24  
2 ; 2 ; 24  

20080104.csv   
X ;Y; Z  
1 ; 1 ; 34  
1 ; 2 ; 23  
1 ; 3 ; 67  
2 ; 1 ; 24  
2 ; 2 ; 24  

......等等。我想编写一个读取行的脚本,如果在给定的行中我们有X = 1和Y = 2,整行将被复制到一个新的csv文件以及filename,给出以下输出:

X ;Y ; Z ; filename  
1  ; 2 ; 6 ; 20080101  
1  ; 2 ; 2 ; 20080102  
1  ; 2 ; NA; 20080103  
1  ; 2 ; 23; 20080104 

知道如何做到这一点以及有关我应该研究的模块或任何示例的任何建议。 感谢您的时间和帮助。

干杯, 纳文

5 个答案:

答案 0 :(得分:4)

这是一个结构良好的问题,逻辑应该是明显的。对于某人提供完成的代码会破坏作业的目的。首先,在问题中添加“作业”标签,然后考虑您想要做什么: 1)遍历文件(跟踪每个文件名,因为它打开) 2)从当前文件中读取行 3)如果满足选择标准(x == 1和y == 2),则写入该行。

要开始使用,请尝试:

import csv, os

for fn in os.listdir():
    if ".csv" in fn:
        with open(fn, 'r', newline='') as f:
            reader = csv.reader(f, delimiter=";")
            for row in reader:
                ...

然后扩展解决方案以打开输出文件并使用csv.writer写入选定的行。

答案 1 :(得分:2)

您可以一次读取每个文件。逐行阅读

files = ['20080101.csv', '20080102.csv', '20080103.csv'] #...etc
for f in files:
    file = open(f, 'r')
    for line in file:
        ray = line.split(';')
        if (ray[0].strip() == '1' and ray[1].strip() == '2'):
            fout = open('output.csv', 'a')
            fout.write(ray[0].strip() + ' ; ' + ray[1].strip() + ' ; ' + ray[2].strip() + ' ; ' + f + '\n')
            fout.close()
    file.close()

经过测试和工作。可能需要稍作修改。

答案 2 :(得分:2)

这应该做的工作:

import glob
import os

outfile = open('output.csv', 'w')
outfile.write('X ; Y ; Z ; filename\n')
for filename in glob.glob('*.csv'):
  if filename == 'output.csv': # Skip the file we're writing.
    continue
  with open(filename, 'r') as infile:
    count = 0 
    lineno = 0 
    for line in infile:
      lineno += 1
      if lineno == 1: # Skip the header line.
        continue
      fields = line.split(';')
      x = int(fields[0])
      y = int(fields[1])
      z = float(fields[2])
      if x == 1 and y == 2:
        outfile.write('%d ; %d ; %g ; %s\n' % (x, y, z, filename))
        count += 1
    if count == 0: # Handle the case when no lines were found.
      outfile.write('1 ; 2 ; NA ; %s\n' % filename)
outfile.close()

请注意,如果您无法控制或信任文件格式,则可能需要处理转换为int / float抛出的异常。

答案 3 :(得分:0)

如果你知道你每天都有一个文件,没有错过的一天,那么我会使用glob('*。csv')获取文件名列表,打开一个一个,然后像Tyler那样读

如果你知道有文件丢失的日子我会使用datetime来标记datetime.date(2008,1,1)并循环增加一天。然后每天我使用.strftime()+'。csv'撰写文件名,并尝试处理文件(如果没有文件,只需用NA写一个重新编码)

答案 4 :(得分:0)

以下内容应该有效:

import csv
with open('output.csv', 'w') as outfile:
    outfile.write('X ; Y ; Z ; filename\n')
    fmt = '1 ; 2 ; %s ; %s\n'
    files = ['20080101.csv', '20080102.csv', '20080103.csv', '20080104.csv']
    for file in files:
        with open(file) as f:
            reader = csv.reader(f, delimiter=';')
            for row in reader:
                if len(row) > 2 and row[0].strip() == '1' and row[1].strip() == '2':
                    outfile.write(fmt % (row[2].strip(), file[:-4]))
                    break
            else:
                outfile.write(fmt % ('NA', file[:-4]))