Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash或python csv多字段处理_Python_Bash_Csv_If Statement_Awk - Fatal编程技术网

bash或python csv多字段处理

bash或python csv多字段处理,python,bash,csv,if-statement,awk,Python,Bash,Csv,If Statement,Awk,我正在从事一个项目,该项目涉及根据csv文件的几个变量/参数创建输出,我正在寻找处理它的最佳方法 我有一个中等大小的csv文件,看起来像: input.csv 我希望输出如下所示: output.csv 但是输出只能是6个人(AABBCD),第3列的总和这里是一段原始代码,您可以轻松地根据需要进行调整 import csv with open('input.csv') as f_in, open('output.csv', 'w') as f_out : csv_r = csv.reade

我正在从事一个项目,该项目涉及根据csv文件的几个变量/参数创建输出,我正在寻找处理它的最佳方法

我有一个中等大小的csv文件,看起来像:

input.csv

我希望输出如下所示:

output.csv


但是输出只能是6个人(AABBCD),第3列的总和这里是一段原始代码,您可以轻松地根据需要进行调整

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)
导入csv
将open('input.csv')作为输入,将open('output.csv','w')作为输出:
csv_r=csv.reader(f_in,分隔符='|')
csv_w=csv.writer(f_out,分隔符=“|”)
col_sum=0
对于csv\u r中的行:
如果len(行)==0:
持续
elif len(行)==3:
字母、人物、值=行
col_sum+=int(值)
如果列总和小于1800:
csv_w.writerow(行)
其他:
第[2]行=0
csv_w.writerow(行)

如果我理解正确。。。来吧

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)
导入csv
def get_子集(行):
子集合=[]
#获取所有行的组合
对于范围(0,长度(行)+1)内的L:
对于itertools.组合(行,L)中的子集:
子集合追加(子集)
#获得少于6个的所有组合

lessthansix=filter(lambda x:True,如果len(x)这里还有一个awk版本,您可以尝试:

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
awk-F\|'
恩特雷斯霍尔德{
最大值=0
如果(值[i]>max),则为(值中的i){
最大值=值[i];j=i
}
如果(最大值>$NF){
A[j]=0美元
总计+=$NF最大值
值[j]=$NF
}
}
结束{
打印总计;对于(A中的i)打印A[i]
}
'set=6 treshold=18000文件|排序

Python一路走来!免责声明:我喜欢Python。现在有一个喜欢Python的实际原因:Python代码可以编写成跨平台的,而当你可以在cygwin上使用bash时,谁愿意这样做?输出必须是你指定的6个吗?你说的2和3是什么意思,即你的output.csv的值大于1800,而值小于1800r即使你说跳过1800以下的值。最后,“替换最高值”的意思是将当前行添加到顶部?@AndreasGS-输出必须是一个由col1中的字母字面关联的组。我想你可能没有读到,我正在寻找col3的和等于或低于18000(而不是1800).#3只是想解决问题,如果#1填满了所有位置,超过18000个。为了纠正这个问题,#3会有选择地通过替换较大的整数来降低总的总和。希望这能解决问题。我很感谢你的评论。@bernie-我承认,我一直在使用cygwin…哈哈,我是在我的fedora盒子上开始编写这个脚本的(因此,我使用bash/awk生成上述文件)。感谢您的输入!我正在研究下面的一些建议。这接近于我所需要的。问题是,它提供了18000以下的最佳组合。我需要它来填充所有6行AABBDC。我不是python大师,所以我可能错过了一些东西,但我的输出是:[[B]、[C]、[Person1]、[3000]、[C]、[Person3]、[5400]、[C]、[Person5]、[9400]]17800.我更感兴趣的是使用18000以下所有点中索引最高的人。谢谢你,我将对此进行更多研究,看看是否可以调整。@LaidBach在你提供的数据集中,没有一个6的组合不超过18000。嗯,使用数据集,我的样本输出加起来不到18000。我将继续测试code您提供了一个更大的数据集。我正在使用python更多地研究CSV和itertools。再次感谢您的帮助。我还看到过滤器中的输入错误为1800而不是18000-让我看看这有什么作用。谢谢!更新:将值更改为18000,并将行参数更改为18000以上)成功了。现在我唯一关心的是,它是否会将较大的数据集排序为只有2As、2Bs、1C、1D。(测试..)谢谢!看起来python是我需要使用的…我希望我能读/写得更好一点。我会考虑修改它以满足我的需要。谢谢!如果我没有弄错的话,这将处理所有与检查列总数和将总数保持在18k以下有关的事情。但是我如何限制此代码只生成6个带2As、2Bs、1C、1D的插槽?目前正在查看更多csv…谢谢!谢谢!(免责声明:仍在学习)我没有看到将输出限制为2A、2B、1C和1D中的6个。除非A[NR]=$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)
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