相对于列提取CSV文件的前20行(降序)行

时间:2014-10-14 23:21:45

标签: python sorting csv highest

我有一个包含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)

2 个答案:

答案 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