【问题标题】:Plot using pandas使用熊猫绘图
【发布时间】:2013-08-21 15:45:17
【问题描述】:

我在列表中有一些事件时间,我想绘制它们的指数加权移动平均值。我可以使用以下代码来做到这一点。

import numpy as np
import matplotlib.pyplot as plt

print "Code runnning"
a=0.01
l = [3.0,7.0,10.0,20.0,200.0]
y = np.zeros(1000)
for item in l:
        y[item]=1
s = np.zeros(1000)
x = np.linspace(0,1000,1000)
for i in xrange(1000):
    s[i] = a*y[i-1]+(1-a)*s[i-1]
plt.plot(x, s)
plt.show()

然而,这显然是一种使用 python 的可怕方式。这样做的正确方法是什么?是否可以在不制作所有这些额外的稀疏数组的情况下做到这一点?

输出应该是这样的。

【问题讨论】:

    标签: python math numpy


    【解决方案1】:

    AFAIK 没有一个很好的方法来使用 numpy 或 scipy.sparse 模块 - scipy.sparse 中的稀疏矩阵被设计为二维矩阵,并首先创建一个你会基本上需要使用您已经在第一个循环中编写的代码(即,在稀疏矩阵中设置所有非零位置),而且总是必须指定两个索引值的额外复杂性。

    好像这还不够糟糕,np.convolve 不适用于稀疏数组,因此您仍然需要在第二个循环中写出计算来计算移动平均值。

    如果您正在寻找一个花哨的numpy 版本,我的建议可能没有太大帮助,那就是依赖 Python 作为通用语言的出色支持:

    import matplotlib.pyplot as plt
    
    a=0.01
    l = set([3, 7, 10, 20, 200])
    s = np.zeros(1000)
    for i in xrange(len(s)):
        s[i] = a * int(i-1 in l) + (1-a) * s[i-1]
    plt.plot(s)
    plt.show()
    

    在这里,我已经将事件索引值存储在 l 中,就像您所做的那样,但是我使用了 set 来使查找时间 O(1)——尽管如果 len(l) 不是很大,您使用简单的列表或元组甚至可能会更好,您需要对其进行测量以确定。然后您可以避免创建y 数组,而只需依靠Iverson's convention 将布尔值x in y 转换为int。您甚至可能不需要显式转换,但我发现显式很有帮助。

    【讨论】:

      【解决方案2】:

      Pandas 想到这个任务:

      import pandas as pd
      
      l = [3.0,7.0,10.0,20.0,200.0]
      s = pd.Series(np.ones_like(l), index=l)
      y = s.reindex(range(1000), fill_value=0)
      pd.ewma(y, 199).plot()
      

      句点 199 与您的参数 alpha 0.01 相关,即 n=2/(a+1)。结果:

      【讨论】:

      • 我从未使用过熊猫。你怎么做才能真正看到情节?
      • 好吧,它只是在 iPython 笔记本中弹出,没有其他事情可做。否则请参阅此处stackoverflow.com/questions/16522380/…。
      • 感谢您的编辑,但图表看起来仍然不像我的。测试时看起来一样吗?
      • @felix,查看我的编辑。我不明白你的y 变量,我以为你在l 中有每日值。
      • 啊,不。 l 是事件发生的时间列表,或者换句话说,当“加一”事件发生时。熊猫可以以某种方式使用l 而不必制作y 吗?
      【解决方案3】:

      我认为您正在寻找这样的东西:

      import numpy as np
      import matplotlib.pyplot as plt
      from scikits.timeseries.lib.moving_funcs import mov_average_expw
      
      l = [ 3.0, 7.0, 10.0, 20.0, 200.0 ]
      y = np.zeros(1000)
      y[[l]] = 1
      emav = mov_average_expw(y, 199)
      plt.plot(emav)
      plt.show()
      

      这利用了来自scikits.timeseries 的mov_average_expw。检查该方法的文档,看看我是如何根据您的代码的 a 变量提出 span 参数的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-16
        • 2019-02-04
        • 2018-07-05
        相关资源
        最近更新 更多