【问题标题】:Calculating and Plotting the Average of every (X) items in a list of (Y) total计算和绘制 (Y) 总计列表中每个 (X) 项目的平均值
【发布时间】:2013-01-26 20:14:41
【问题描述】:

在发布此内容之前,我已经搜索并搜索了(4 天)。如果它太初级,我提前道歉,浪费你的时间。我已经使用 pyplot 和 matplotlib 通过使用他们的教程示例成功地生成了一些基本图,但对我需要完成的工作无济于事。

基本上:

  • 我有一个存在于单个文件中的数字列表。
  • 每一行都包含一个数字,对应于完成所需的毫秒数 某个重复的任务。
  • 此文件中有超过 100 万个条目,而且还可以增长。

20 例:

173
1685
1152
253
1623
390
84
40
319
86
54
991
1012
721
3074
4227
4927
181
4856
1415

最终我需要做的是计算一个范围内的单个总数(均匀分布在条目的绝对总数上)——然后使用 python 的任何绘图库绘制这些平均值。我考虑过使用 pyplot 以方便使用。

  • X 轴对应已完成任务的总数,因为 Y 轴表示完成任务所需的毫秒数(在本示例中为每 5 次完成所需的平均时间)。

即:

Entries 1-5 = (plottedTotalA)
Entries 6-10 = (plottedTotalB)
Entries 11-15 = (plottedTotalC)
Entries 16-20 = (plottedTotalD)

据我所知,我不需要无限期地存储变量的值,只需在处理它们时(按顺序)将它们传递给绘图仪。我已经尝试了以下示例来汇总上述 20 个列表中的 5 个条目(有效),但我不知道如何一次动态地传递 5 个条目直到完成,同时保留计算出的平均值最终将传递给 pyplot。

例如:

Python 2.7.3 (default, Jul 24 2012, 10:05:38) 
[GCC 4.7.0 20120507 (Red Hat 4.7.0-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> plottedTotalA = ['173', '1685', '1152', '253', '1623']
>>> sum(float(t) for t in plottedTotalA)
4886.0

【问题讨论】:

    标签: python numpy python-2.7 matplotlib


    【解决方案1】:

    假设您在名为 x 的列表中有 n 个值。然后将 x 重塑为一个 5 列的数组 A 并计算每行的平均值。然后你可以简单地绘制结果向量。

    x = np.array(x)
    n = x.size
    A = x[:(n // 5) * 5].reshape(5, -1)
    y = A.mean(axis = 0)
    plot(y)
    

    编辑:根据 tacaswell 的评论更改了我的代码

    但是,如果您实际上有超过一百万个条目,您可能会遇到内存问题。您也可以使用名称 x 而不是 A 和 y。这样您将覆盖初始数据并节省一些内存。

    希望对你有帮助

    【讨论】:

    • 如果len(x) % 5 != 0 会爆炸。我会使用A = x[:(n // 5) * 5].reshape(5, -1)
    • @user 感谢您的建议。我很欣赏快速反应。我能够使用您的方法进行绘图。我现在正试图弄清楚如何使用您提供的内容,以及 sotapme 给了我什么来绘制平均值。再次感谢!
    • @tcaswell 感谢您的洞察力。我执行了你的建议。
    【解决方案2】:

    我认为问题是如何从文件生成的列表中获取 5 个项目。 正如你所说:

    我不知道如何一次动态地传递 5 个直到完成,

    我使用了/dev/random,因为它永无止境且随机,可模拟您的大文件并显示处理大文件而不读取列表或类似的数据。

    ################################################################################
    def bigfile():
        """Never ending list of random numbers"""
        import struct
        with open('/dev/random') as f:
            while True:
                yield  struct.unpack("H",f.read(2))[0]
    ################################################################################
    def avg(l):
        """Noddy version"""
        return sum(l)/len(l)
    ################################################################################
    
    bigfile_i = bigfile()
    
    import itertools
    ## Grouper recipe @ itertools
    by_5  = itertools.imap(None, *[iter(bigfile_i)]*5)
    
    # Only take 5, 10 times.
    for x in range(10):
        l = by_5.next()
        a = avg(l)
        print l, a ## PLOT ?
    

    编辑

    剩余部分发生的细节。

    如果我们假设文件有 11 行,我们每次取 5 行:

    In [591]: list(itertools.izip_longest(*[iter(range(11))]*5))
    Out[591]: [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, None, None, None, None)]
    
    In [592]: list(itertools.imap(None, *[iter(range(11))]*5))
    Out[592]: [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9)]
    
    In [593]: list(itertools.izip(*[iter(range(11))]*5))
    Out[593]: [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9)]
    

    在一种情况下,izip_longest 将用None 填充剩余部分,而imapizip 将截断。我可以想象 OP 可能会希望使用 itertools.izip_longest(*iterables[,fillvalue]) 作为可选填充值,尽管 NoneNo Values 的一个很好的标记。

    我希望这能说明其余部分会发生什么。

    【讨论】:

    • 非常感谢您的帮助;我已经实现了你的想法,现在可以直接从我的文件中一次看到 5 个平均值。但是 - 如果我不知道范围怎么办。例如,我想一次取 100 个,直到文件结束。 (可能是 500k、100 万或几千。它总是可变的。)其余部分是否会使用 mod 之类的东西四舍五入?我可以去掉非 100 的末端部分,还是除以 100 以获得确切的指标?
    猜你喜欢
    • 2021-01-17
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多