0

我正在开发一个项目,该项目涉及基于 csv 文件的一些变量/参数创建输出,我正在寻找处理它的最佳方法。

我有一个中等大小的 csv 文件,如下所示:

输入.csv

B|Person1|3000
A|Person2|3000
C|Person3|5400
A|Person4|1700
C|Person5|9400
D|Person6|2400
B|Person7|2000
A|Person8|3400
A|Person9|1000
A|Person10|2500
A|Person11|3000

我希望输出看起来像:

输出.csv

A|Person2|3000
A|Person4|1700
B|Person1|3000
B|Person7|2000
C|Person3|5400
D|Person6|2400

但是输出只能是 6 人(AABBCD)并且第 3 列的总和 <= 18000。我希望从input.csv的第一行向下创建输出:

  1. 如果 row(s) 为空,则根据字母 AD (Column1) 填写人,[可选]忽略第 3 列的总和。
  2. 如果行不为空且第 3 列的总和低于 1800 - 跳过(继续)。
  3. 如果行不为空且第 3 列的总和超过 1800,则替换最高值(继续)。
  4. [可选]完成后,重新开始该过程,检查是否可以用更高的值替换任何人;本质上是创建一个 18000 人以下最有价值的人的名单。

注意:所有 6 个参数必须根据它们的第 1 列位置填写。

起初我想生成一个output.csv文件,其中第一列包含 AABBCD 并使用 awk 匹配和条件语句添加行。然后我开始研究使用 awk 数组(将 3 列传递给 3 个数组并根据索引分配值)...

但是现在,似乎 python 可能是处理 csv 文件时要走的路,但在使用 python 编写脚本时,我仍然是新手;您能否推荐适当的路径来产生所需的输出?

非常感谢,这一直让我发疯。

编辑:简而言之 - 仅匹配前 6 名(AABBCD:具有 2As、2Bs、1C、1D)并且第 3 列的最终总和 <= 18000 美元。

4

3 回答 3

1

Here is also an awk version you could try:

awk -F\| '
  NR<=set{
    A[NR]=$0
    total+=$NF
    values[NR]=$3
    next
  }

  total>treshold{
    max=0
    for(i in values) if (values[i]>max){
      max=values[i]; j=i
    }
    if ( max > $NF) {
      A[j]=$0
      total+=$NF-max
      values[j]=$NF
    }
  }

  END{
    print total; for(i in A) print A[i]
  }
' set=6 treshold=18000 file | sort
于 2013-03-23T15:42:13.287 回答
1

这是一段原始代码,您可以从中轻松适应您的需要

import csv
with open('input.csv') as f_in, open('output.csv', 'w') as f_out :
   csv_r = csv.reader(f_in, delimiter='|')
   csv_w = csv.writer(f_out, delimiter='|')
   col_sum = 0
   for row in csv_r :
       if len(row) == 0 :
           continue
       elif len(row) == 3 :
           letter, person, value = row
           col_sum += int(value)
           if col_sum < 1800 :
               csv_w.writerow(row)
           else :
               row[2] = 0
               csv_w.writerow(row)
于 2013-03-22T22:48:31.710 回答
0

如果我正确理解了一切……就这样吧。

import csv

def get_subset(rows):
    sub_sets = []
    #get all combinations of rows
    for L in range(0, len(rows)+1):
        for subset in itertools.combinations(rows, L):
            sub_sets.append(subset)

    #get all combinations less than six
    lessthansix = filter(lambda x: True if len(x) <= 6 else False, sub_sets)
    #get all combinations less than or equal to max
    lessthanmax = filter(lambda x: True if sum([int(col[2]) for col in x]) <= 18000 else False, lessthansix)
    #sort the less than max groups by sum of col 3
    closesttomax = sorted(lessthanmax, reverse=True, key=lambda x: sum([int(col[2]) for col in x])) 

    return closesttomax[0]

with open("test.csv", 'r') as f:
    reader = csv.reader(f, delimiter="|")
    #filter out all rows that have col 3 less than 1800
    rows = [row for row in reader if int(row[2]) > 1800]
    subset = get_subset(rows)
    sorted_rows = sorted(subset, key=lambda x: x[0])
    with open("out.csv", 'w') as o:
        writer = csv.writer(o)
        print sorted_rows
        print sum([int(col[2]) for col in sorted_rows])
        for row in sorted_rows:
            writer.writerow(row)
于 2013-03-22T23:24:45.073 回答