bash或python csv多字段处理
我正在从事一个项目,该项目涉及根据csv文件的几个变量/参数创建输出,我正在寻找处理它的最佳方法 我有一个中等大小的csv文件,看起来像: input.csv 我希望输出如下所示: output.csvbash或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
但是输出只能是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