查找特定列的最大频率

时间:2018-05-29 08:41:03

标签: python

输入文件,

ID,ROLLNO,AMOUNT,COUNT
1,0700,1500,10
2,900,500,3
3,0700,500,10
4,900,150,9
5,0700,1000,10
6,01620,80,5
7,0700,1000,10
8,0700,1000,10

我必须找到具有ROLLNO特定AMOUNT的{​​{1}}和COUNT的{​​{1}}和AMOUNT。例如,ROLLNO 900 AMOUNT 150拥有最多COUNT,因此应该在输出中。 此外,如果ROLLNO具有相同的COUNT值,则必须对相应的AMOUNT S进行总计以得到结果。例如,对于ROLLNO 0700,所有COUNT都相同,因此其AMOUNT应为1500+500+1000+1000+1000 = 5000;

预期的输出将是这样的,

ID,ROLLNO,COUNT,AMOUNT
6,900,9,150
5,01620,5,80
2,0700,10,5000

最好的方法是什么?非常感谢任何帮助。

编辑:我的坏。 ID在这里并不重要。我只是提出了一些价值观,这就是全部。

3 个答案:

答案 0 :(得分:1)

如果pandas可行,则应该这样做:

df = pd.read_csv('yourfilename.csv')
df.groupby(['ROLLNO', 'COUNT'])['AMOUNT'].sum()\
  .reset_index()\
  .sort_values(by=['ROLLNO', 'COUNT'], ascending=False)\
  .drop_duplicates('ROLLNO')
#   ROLLNO  COUNT  AMOUNT
#3    1620      5      80
#2     900      9     150
#0     700     10    5000

请注意,这并不能解决ID问题,因为您不清楚如何确定ID。

如果您有大量csv文件,则可以使用chunksize参数:

chunksize = 10

prefinal = pd.DataFrame()

for chunk in pd.read_csv(filename, chunksize=chunksize):
    grouped = chunk.groupby(['ROLLNO', 'COUNT'])['AMOUNT'].sum()\
                   .reset_index()\
                   .sort_values(by=['ROLLNO', 'COUNT'], ascending=False)\
                   .drop_duplicates('ROLLNO')
    prefinal = pd.concat([prefinal, grouped], ignore_index=True)

final = prefinal.groupby(['ROLLNO', 'COUNT'])['AMOUNT'].sum()\
                .reset_index()\
                .sort_values(by=['ROLLNO', 'COUNT'], ascending=False)\
                .drop_duplicates('ROLLNO')

上面的示例将一次读取10行文件并对其进行处理,最后将所有这些文件组合在一起。

答案 1 :(得分:1)

以下是使用标准库中的collections.defaultdictitertools.groupby的解决方案。

如果您需要特定格式,则可以使用pandas

from collections import defaultdict
from itertools import groupby
from io import StringIO
import csv

mystr = StringIO("""ID,ROLLNO,AMOUNT,COUNT
1,0700,1500,10
2,900,500,3
3,0700,500,10
4,900,150,9
5,0700,1000,10
6,01620,80,5
7,0700,1000,10
8,0700,1000,10""")

d = defaultdict(int)

with mystr as fin:
    reader = csv.DictReader(fin)
    for line in reader:
        d[(line['ROLLNO'], int(line['COUNT']))] += int(line['AMOUNT'])

sorted_d = sorted(d.items(), reverse=True)
res = [next(j) for _, j in groupby(sorted_d, key=lambda x: x[0][0])]

[(('900', 9), 150),
 (('0700', 10), 5000),
 (('01620', 5), 80)]

答案 2 :(得分:0)

如果你想坚持使用普通的python,你可以使用词典:

file = open("input.txt", "r")
dct = {}
headers = file.readline()
for line in file:
    lst = line.split(",")
    if lst[1] not in dct:
        dct[lst[1]] = lst
        continue
    if dct[lst[1]][3] < lst[3]:
        dct[lst[1]] = lst

print headers
for row in dct.values():
    print ','.join(row)

更新:由于这可能不明确,因此将字典键设置为ROLLNO值会强制执行唯一约束:对于发生的每个ROLLNO值,您的字典dct将记录第四列中具有最大值的行(COUNT)