【问题标题】:How group by sum and average column in python?python中如何按总和和平均列分组?
【发布时间】:2016-01-22 08:12:41
【问题描述】:

作为输入,我有一个 CSV 文件,其中包含每次的时间和一堆数字。

Time,F1,F2,F3
8:11,5,2,4
9:25,9,8,2
9:39,7,3,2
9:53,6,5,1
10:07,4,6,7
10:21,7,3,1
10:35,5,6,7
11:49,1,2,1
12:03,3,3,1

我想输出按 Avg 和 Sum 列分组的每小时的表格:

Time,SUM F1,SUM F2,SUM F3,AVG F1,AVG F2,AVG F3
8:00,5,2,4,5,2,4
9:00,22,16,5,7.3,5.3,1.6
10:00,16,15,15,5.3,5,5
11:00,1,2,1,1,2,1
12:00,3,3,1,3,3,1

到目前为止,我一直在用字典来做,其中小时是键,值是计数和总和的列表,然后将总和除以计数得到平均值。 我确信必须有更清洁的方法来做到这一点。也许一些图书馆可以使用这个。有什么建议吗?

【问题讨论】:

  • 你的方法很好。也没有那么多代码。将内容添加到三个字典的循环,每个字典使用 setdefault(hour, []).append(F1) 和 setdefault(hour, []).append(F2) 和 setdefault(hour, []).append(F3)。然后对于每个字典,您每小时遍历一次并在列表上调用“sum”并除以 count(list),同时注意处理列表为空时发生的情况。
  • Pandas 是用于此类数据处理的好库:pandas.pydata.org

标签: python csv pandas aggregate


【解决方案1】:

pandas 解决方案:

import pandas as pd

df = pd.read_csv('f123.csv')
df['Time'] = df['Time'].apply(lambda x: x.split(':')[0] + ':00')
by_hour = df.groupby('Time')
data = {}
for name in ['F1', 'F2', 'F3']:
    data['SUM ' + name] = by_hour[name].sum()
    data['AVG ' + name] = by_hour[name].mean()
res = pd.DataFrame(data)
print(res)

打印:

         AVG F1    AVG F2    AVG F3  SUM F1  SUM F2  SUM F3
Time                                                       
10:00  5.333333  5.000000  5.000000      16      15      15
11:00  1.000000  2.000000  1.000000       1       2       1
12:00  3.000000  3.000000  1.000000       3       3       1
8:00   5.000000  2.000000  4.000000       5       2       4
9:00   7.333333  5.333333  1.666667      22      16       5

另存为 csv 文件:

res.to_csv('res.csv')

这是res.csv的内容:

Time,AVG F1,AVG F2,AVG F3,SUM F1,SUM F2,SUM F3
10:00,5.333333333333333,5.0,5.0,16,15,15
11:00,1.0,2.0,1.0,1,2,1
12:00,3.0,3.0,1.0,3,3,1
8:00,5.0,2.0,4.0,5,2,4
9:00,7.333333333333333,5.333333333333333,1.6666666666666667,22,16,5

【讨论】:

  • 很好的解决方案!如果时间旁边的日期列采用“22-01-16”格式,您将如何处理新的日子?
  • 很好,它有帮助。 Pandas 非常擅长阅读和处理一般日期。但是,在评论中回答新问题确实很麻烦。从这里提出一个新问题并将其链接到评论中会更容易。我去看看。
  • Pands 看起来确实很棒,但是在那里操作数据乍一看不是很直观,也许我应该参加其中的 python-academy 课程。在这里我添加了新问题:stackoverflow.com/questions/34944183/…
【解决方案2】:

以下内容应该可以帮助您入门,它使用 Python 的 csv 模块来处理文件,并使用 itertools.groupby 按小时对条目进行分组:

import csv
from itertools import groupby, chain

with open('input.csv', 'rb') as f_input, open('output.csv', 'wb') as f_output:
    csv_input = csv.reader(f_input)
    csv_output = csv.writer(f_output)
    header = next(csv_input)
    csv_output.writerow(["Time","SUM F1","SUM F2","SUM F3","AVG F1","AVG F2","AVG F3"])

    for k, g in groupby(csv_input, lambda x: int(x[0].split(':')[0])):
        entries = [(int(f1), int(f2), int(f3)) for t, f1, f2, f3 in g]
        sums = [(sum(x), sum(x)/float(len(entries))) for x in zip(*entries)]
        row = ['{}:00'.format(k)] + list(chain.from_iterable(zip(*sums)))
        csv_output.writerow(row)

这将为您提供如下所示的输出 csv 文件:

 Time,SUM F1,SUM F2,SUM F3,AVG F1,AVG F2,AVG F3
 8:00,5,2,4,5.0,2.0,4.0
 9:00,22,16,5,7.333333333333333,5.333333333333333,1.6666666666666667
 10:00,16,15,15,5.333333333333333,5.0,5.0
 11:00,1,2,1,1.0,2.0,1.0
 12:00,3,3,1,3.0,3.0,1.0

zip 用于转置列条目。

使用 Python 2.7.9 测试

【讨论】:

    猜你喜欢
    • 2015-07-31
    • 2016-09-25
    • 2018-11-29
    • 2017-10-25
    • 1970-01-01
    • 2020-04-15
    • 2022-01-08
    相关资源
    最近更新 更多