我有一个包含3列的CSV文件,如下所示:
a,b,c
1,1,2
1,3,5
1,5,7
.
.
2,3,4
2,1,5
2,4,7
我希望输出像
a,b,c
1,5,7
1,3,5
1,1,2
.
.
2,4,7
2,3,4
2,1,5
即,对于a列中的每个元素,我想只有前20行(20个最高'b'值)行。 请原谅我糟糕的解释。到目前为止我已经尝试了这个但是没有给出我所需的输出:
import csv
import heapq
from itertools import islice
csvout = open ("output.csv", "w")
writer = csv.writer(csvout, delimiter=',',quotechar='"', lineterminator='\n', quoting=csv.QUOTE_MINIMAL)
freqs = {}
with open('input.csv') as fin:
csvin = csv.reader(fin)
rows_with_mut = ([float(row[1])] + row for row in islice(csvin, 1, None) if row[2])
for row in rows_with_mut:
cnt = freqs.setdefault(row[0], [[]] * 20)
heapq.heappushpop(cnt, row)
for assay_id, vals in freqs.iteritems():
output = [row[1:] for row in sorted(filter(None, vals), reverse=True)]
writer.writerows(output)
答案 0 :(得分:2)
由于文件仅在列a上排序,因此您必须在列b和b上对其进行排序。 c也是。我建议使用natsort,按升序或降序对文件进行排序,而不是循环遍历文件,并为列a的每个值打印20行。
有些事情:
import natsort
with open('myfile.csv', 'r') as inFile:
lines = inFile.readlines()
sortedList = reversed(natsort.natsorted(lines))
#alternatively, you might want to try natsort.versorted() which is used for version numbers
counter = 0
prevAVal=currentAval=1
for line in sortedList:
currentAVal = ",".split(line)[0]
if currentAVal != prevAval:
counter = 0
if counter < 20 :
print line
counter = counter + 1
prevAVal=currentAVal
答案 1 :(得分:1)
关于downvoting的风险,你可以使用一个简单的bash脚本:
#!/bin/bash
all=$(cat) #read from stdin
echo "$all" | head -n 1 #echo the header of the file
allt=$(echo "$all" | tail -n +2) #remove the header from memory
avl=$(echo "$allt" | cut -d ',' -f 1 | sort | uniq) #find all unique values in the a column
for av in $avl #iterate over these values
do
echo "$allt" | grep "^$av," | sort -t$',' -k2nr | head -n 20 #for each value, find all lines with that value and sort them, return the top 20...
done
您可以在命令行中使用以下命令运行:
bash script.sh < data.csv
它将在终端上打印结果......
示例强>:
如果使用您的样本值(不带“点” - ),则获得:
user@machine ~> bash script.sh < data.csv
a,b,c
1,5,7
1,3,5
1,1,2
2,4,7
2,3,4
2,1,5
如果要将结果写入文件(例如data2.csv
),请使用:
bash script.sh < data.csv > data2.csv
不读取和写入同一文件:不要运行bash script.sh < data.csv > data.csv
。