Извлечь 20 верхних (нисходящих) строк файла CSV относительно столбца
У меня есть файл CSV с 3 столбцами, который выглядит следующим образом:
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 ответа
На риск понижения вы можете использовать простой скрипт 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
,
Так как файл отсортирован только по столбцу a, вы должны также отсортировать его по столбцу b & c. Я предлагаю использовать natsort, сортировать файл в порядке возрастания или убывания, а не зацикливать его и печатать 20 строк для каждого значения столбца a.
Что-то вроде:
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