如何通过移动一行使用python在csv文件中创建新列

时间:2014-07-19 21:51:34

标签: python list csv

我有以下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

我想通过添加新列" PSR"来创建output.csv文件。在第1栏之后"否"。此列值取决于列" PSR"值。对于第1行," PSR"应为零。从下一个记录开始,它取决于" CSR"上一行中的值。如果现在和以前的记录CSR值相同,那么" PSR"应为零。如果不是,PSR值应具有先前的CSR值。例如,第2行的CSR值为1300,与第1行的值(1200)不同。因此第2行的PSR值应为1200.在第2行和第3行中,CSR值相同。因此第3行的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并迭代列表中的对象。将第5列复制到列表中的第2列。将它向下移一行。
  2. 如果两个值相同,则检查第2和第5列(PCR和CSR)中的值。将PCR值替换为零。
  3. 我在编写第一步时遇到问题。我能够复制列但无法移动它。第二步非常简单。

    此外,我不确定这种方法是否正确任何指针/推荐都会非常有用。

    注意:我无法在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 :(得分: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 

答案 1 :(得分:0)

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)

答案 2 :(得分: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)

答案 3 :(得分:0)

或者,使用DictReader的{​​{1}}和DictWriter功能更加轻松:

csv