根据以后的CSV值更新初始CSV值?

时间:2015-05-21 23:22:24

标签: python csv

我有一个相当基本的问题,我想知道使用Python的最佳解决方案是什么。我有一组CSV文件,在每个文件中,我有一些逗号分隔的元素。重要的是,每个CSV文件中有两个不同的行块,让我们说"块1" " Block 2"。块1和块2之间的某些值重叠(特定感兴趣的项目:特定.jpg文件的名称),但顺序会有所不同。以下是文件组织方式的缩短版本:

Trial,Image,Type,Reps
1,511.jpg,T,1REP
2,101a.jpg,2,1REP
3,185a.jpg,5,3REP
4,566.jpg,T,3REP
5,560.jpg,T,3REP

Trial,Image,Type,Reps,Keypress
1,101a.jpg,2,1REP,1
2,185a.jpg,5,3REP,0
3,511.jpg,T,1REP,1
4,560.jpg,T,3REP,1
5,566.jpg,T,3REP,0

为了澄清一下,这是一个实验的日志文件,其中Block 1是研究图像的时间。 "类型"对应于图片的类型," Reps"对应于整体看图片的次数(1或3次),这两者都不是我想要达到的目标。我想做的是:对于第一个块中的每一行,匹配第二个块中相同.jpg文件的名称。然后我需要在" 1"上添加Block 1行。或" 0"根据相应的" Keypress"第2区是" 1"或" 0"元件。基本上,当在图片上进行测试时,他们按下" 1"或" 0"我想在学习期间对哪些人的新闻进行排序。重要的是,我需要保留Block 1(图像的研究顺序)的顺序,无论我采取什么解决方案。

抱歉这个要求是基本的......我正在学习。

2 个答案:

答案 0 :(得分:1)

假设csv文件足够小,我只需使用字典{}将每个文件的值映射到彼此。

首先加载Block 2中的所有值。

d= {}

with open('some1.csv', 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
        num, file_name, third, num = row  # 1,a.jpg,XYZ,1
        d[file_name] = num

现在,当在块1上进行迭代时,检索从块2中存储的值,并将它们附加到数据中。

with open('some2.csv', 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
        num, file_name, third, num = row  # 1,a.jpg,XYZ,1
        lst = [num, file_name. third, num, d.get(file_name, -1)]
        # now convert `lst` to csv, and write to file

请注意,如果在存储的Block 2数据中找不到匹配的文件名,则第二个代码块使用值-1

答案 1 :(得分:1)

你的问题根本不是我所说的基本问题(与排序无关)。事实上,进行所需的处理是相当复杂的。基本上每个文件必须被读取两次,首先从第二个块中提取所需的信息,然后再次更新其中的第一个块。此外,每次读取文件分为两个子步骤,因为每个文件中有两种csv数据,每次传递都必须单独处理。

由于现场更新文件相当困难,因此首先将文件的更新版本写入单独的临时文件,如果处理完成且没有错误,则替换原始文件。

import csv
import shutil
from tempfile import NamedTemporaryFile

TRIAL = 0
IMAGE = 1
KEYPRESS = 4
filename = 'backsorting.csv'
img_resp_map = {}

# first pass
with open(filename, 'rb') as csvfile:
    reader = csv.reader(csvfile)

    # skip over first block
    next(reader)  # header
    while True:
        row = next(reader)
        if not row[TRIAL].isdigit():  # header of second block?
            break

    # use data in second block to create an image-to-response mapping
    for row in reader:
        img_resp_map[row[IMAGE]] = row[KEYPRESS]

# second pass
with open(filename, 'rb') as csvfile:
    reader = csv.reader(csvfile)
    fields = next(reader)  # get header of first block
    with NamedTemporaryFile('wb', dir='.', delete=False) as tempcsv:
        writer = csv.writer(tempcsv)
        writer.writerow(fields + ['Keypress'])  # new header with added field

        # copy and update rows of first block by appending the new field
        for row in reader:
            if not row[TRIAL].isdigit():  # header of second block?
                break
            writer.writerow(row+[img_resp_map[row[IMAGE]]])

        # copy second block of file unchanged
        writer.writerow(row)  # header (already read)
        writer.writerows(reader)

    # NOTE: the following is dangerous since it wipes out the original file
    shutil.move(tempcsv.name, filename)  # replace original file with temp one

我的测试文件名为backsorting.csv,最初包含此内容:

Trial,Image,Type,Reps
1,511.jpg,T,1REP
2,101a.jpg,2,1REP
3,185a.jpg,5,3REP
4,566.jpg,T,3REP
5,560.jpg,T,3REP
Trial,Image,Type,Reps,Keypress
1,101a.jpg,2,1REP,1
2,185a.jpg,5,3REP,0
3,511.jpg,T,1REP,1
4,560.jpg,T,3REP,1
5,566.jpg,T,3REP,0

运行脚本后,其内容已更改为:

Trial,Image,Type,Reps,Keypress
1,511.jpg,T,1REP,1
2,101a.jpg,2,1REP,1
3,185a.jpg,5,3REP,0
4,566.jpg,T,3REP,0
5,560.jpg,T,3REP,1
Trial,Image,Type,Reps,Keypress
1,101a.jpg,2,1REP,1
2,185a.jpg,5,3REP,0
3,511.jpg,T,1REP,1
4,560.jpg,T,3REP,1
5,566.jpg,T,3REP,0