如何在Python中通过移动一行创建CSV文件的新列

1 投票
4 回答
4372 浏览
提问于 2025-04-18 13:59

我有一个像下面这样的CSV文件。这个文件很大,里面有成千上万条记录。

input.csv

No;Val;Rec;CSR
0;10;1;1200
0;100;2;1300
0;100;3;1300
0;100;4;1400
0;10;5;1200
0;11;6;1200

我想创建一个output.csv文件,在第一列“No”后面添加一个新列“PSR”。这个新列的值取决于“CSR”列的值。对于第一行,“PSR”的值应该是零。从第二行开始,它的值取决于上一行的“CSR”值。如果当前行和上一行的“CSR”值相同,那么“PSR”的值就为零。如果不相同,PSR的值就等于上一行的“CSR”值。举个例子,第二行的“CSR”值是1300,而第一行的值是1200,所以第二行的“PSR”值应该是1200。而在第二行和第三行中,“CSR”值是相同的,所以第三行的“PSR”值就为零。因此,新的“PSR”值依赖于当前行和上一行的“CSR”值。

Output.csv

No;PCR;Val;Rec;CSR
0;0;10;1;1200
0;1200;100;2;1300
0;0;100;3;1300
0;1300;100;4;1400
0;1400;10;5;1200
0;0;11;6;1200

我的方法:

  1. 使用csv.reader读取文件,并将对象放入一个列表中。把第五列的值复制到列表的第二列,并向下移动一行。
  2. 然后检查第二列和第五列(PCR和CSR)的值,如果两个值相同,就把PCR的值替换为零。

我在第一步的编码上遇到了问题。我能复制这一列,但无法将它向下移动。此外,第二步相对简单。

另外,我不确定这个方法是否正确,任何建议或推荐都会很有帮助。

注意:我在CentOS上无法安装Pandas,所以不使用这个模块的帮助会更好。

我的代码:

with open('input.csv', 'r') as input, open('output.csv', 'w') as output:
        reader = csv.reader(input, delimiter = ';')
        writer = csv.writer(output, delimiter = ';')
        mylist = []                                        
        header = next(reader)                           
        mylist.append(header)
        for rec in reader:
                mylist.append(rec)                      
                rec.insert(1, rec[3])
                mylist.append(rec)
        writer.writerows(mylist)

4 个回答

0

就按照你说的那样写代码。把之前的CSR存起来,然后在下一次循环的时候用到它;记得要更新它哦。

import csv
with open('input.csv', 'r') as input, open('output.csv', 'w') as output:
        reader = csv.reader(input, delimiter = ';')
        writer = csv.writer(output, delimiter = ';')
        mylist = []
        header = next(reader)
        mylist.append(header)
        mylist.insert(1,'PCR')
        prev_csr = 0
        for rec in reader:
                rec.insert(1,prev_csr)
                mylist.append(rec)
                prev_csr = rec[4]
        writer.writerows(mylist)
0

或者,更简单的方法是使用 csv 模块里的 DictReaderDictWriter 功能:

input_header  = ['No','Val','Rec','CSR']
output_header = ['No','PCR','Val','Rec','CSR']

with open('input.csv', 'rb') as in_file, open('output.csv', 'wb') as out_file:
    in_reader, out_writer = DictReader(in_file, input_header, delemeter =';'), DictWriter(out_file, output_header, delemeter =';')
    in_reader.next()         # skip the header
    out_writer.writeheader() # place the output header
    last_csr = None
    for row in in_reader():
        current_csr = row['CSR']
        row['PCR']  = last_csr if current_csr != last_csr else 0
        last_csr    = current_csr
        out_writer.writerow(row)
0

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,但其实只要理解了背后的原理,就能找到解决办法。

比如说,当你在写代码的时候,可能会发现某些功能没有按预期工作。这时候,检查你的代码和使用的工具的文档是很重要的。文档就像是使用说明书,可以告诉你怎么正确使用这些工具。

另外,很多时候,其他开发者也会遇到类似的问题,他们会在网上分享自己的解决方案。像StackOverflow这样的社区就是一个很好的地方,你可以在这里找到别人遇到的问题和解决办法。

总之,遇到问题不要慌,先查查文档,看看有没有人遇到过类似的情况,通常都能找到解决的办法。

with open('input.csv', 'r') as input, open('output.csv', 'w') as output:
    reader = csv.reader(input, delimiter = ';')
    writer = csv.writer(output, delimiter = ';')

    header = next(reader)
    header.insert(1, 'PCR')
    writer.writerow(header)

    prevRow = next(reader)
    prevRow.insert(1, '0')
    writer.writerow(prevRow)
    for row in reader:
        if prevRow[-1] == row[-1]:
            val = '0'
        else:
            val = prevRow[-1]
        row.insert(1,val)
        prevRow = row
        writer.writerow(row)
1

如果你愿意尝试非Python的解决方案,awk可能是个不错的选择:

awk 'NR==1{$2="PSR;"$2}NR>1{$2=($4==a?0";"$2:+a";"$2);a=$4}1' FS=';' OFS=';' file
No;PSR;Val;Rec;CSR
0;0;10;1;1200
0;1200;100;2;1300
0;0;100;3;1300
0;1300;100;4;1400
0;1400;10;5;1200
0;0;11;6;1200

Awk几乎在所有Linux系统中都有,它就是为了处理这种任务而设计的。它处理文件的速度非常快。你只需在最后加上重定向 > output.csv,就可以把结果保存到一个文件里。

用简单的python方法,逻辑是一样的:

#!/usr/bin/env python

last = "0"

with open('input.csv') as csv:
    print next(csv).strip().replace(';', ';PSR;', 1)
    for line in csv:
        field = line.strip().split(';')
        if field[3] == last: field.insert(1, "0")
        else: field.insert(1, last)
        last = field[4]
        print ';'.join(field)

这样也能产生相同的结果:

$ python parse.py
No;PSR;Val;Rec;CSR
0;0;10;1;1200
0;1200;100;2;1300
0;0;100;3;1300
0;1300;100;4;1400
0;1400;10;5;1200
0;0;11;6;1200

同样,只需重定向输出,就能保存结果:

$ python parse.py > output.csv 

撰写回答