【问题标题】:Pandas: how to plot yearly data on top of each otherPandas:如何将年度数据相互叠加
【发布时间】:2012-05-14 13:38:42
【问题描述】:

我有一系列按时间值(浮点数)索引的数据,我想获取该系列的多个部分并将它们相互叠加。例如,假设我在 20 周内大约每 10 分钟获取一次股票价格,我想通过绘制 20 条股票价格线来查看每周模式。所以我的 X 轴是一周,我有 20 条线(对应一周内的价格)。

更新

索引不是均匀间隔的值,它是一个浮点数。是这样的:

t = np.arange(0,12e-9,12e-9/1000.0)
noise = np.random.randn(1000)/1e12
cn = noise.cumsum()
t_noise = t+cn
y = sin(2*math.pi*36e7*t_noise) + noise
df = DataFrame(y,index=t_noise,columns=["A"])
df.plot(marker='.')
plt.axis([0,0.2e-8,0,1])

所以索引不是均匀间隔的。我正在处理来自模拟器的电压与时间数据。我想知道如何创建一个时间窗口 T,并将 df 拆分为 T 长的块并将它们绘制在彼此之上。因此,如果数据长度为 20*T,那么我将在同一个图中有 20 条线。

很抱歉给您带来了困惑;我使用股票类比认为它可能会有所帮助。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    假设以pandas.TimeSeries对象为起点,可以分组 ISO 周数和 ISO 工作日的元素 datetime.date.isocalendar()。以下语句忽略了 ISO 年份,汇总了每天的最后一个样本。

    In [95]: daily = ts.groupby(lambda x: x.isocalendar()[1:]).agg(lambda s: s[-1])
    
    In [96]: daily
    Out[96]: 
    key_0
    (1, 1)     63
    (1, 2)     91
    (1, 3)     73
    ...
    (20, 5)    82
    (20, 6)    53
    (20, 7)    63
    Length: 140
    

    可能有更简洁的方法来执行下一步,但目标是将索引从元组数组更改为 MultiIndex 对象。

    In [97]: daily.index = pandas.MultiIndex.from_tuples(daily.index, names=['W', 'D'])
    
    In [98]: daily
    Out[98]: 
    W   D
    1   1    63
        2    91
        3    73
        4    88
        5    84
        6    95
        7    72
    ...
    20  1    81
        2    53
        3    78
        4    64
        5    82
        6    53
        7    63
    Length: 140
    

    最后一步是从 MultiIndex,为每个工作日创建列,并将工作日数字替换为缩写,以提高可读性。

    In [102]: dofw = "Mon Tue Wed Thu Fri Sat Sun".split()
    
    In [103]: grid = daily.unstack('D').rename(columns=lambda x: dofw[x-1])
    
    In [104]: grid
    Out[104]: 
        Mon  Tue  Wed  Thu  Fri  Sat  Sun
    W                                    
    1    63   91   73   88   84   95   72
    2    66   77   96   72   56   80   66
    ...
    19   56   69   89   69   96   73   80
    20   81   53   78   64   82   53   63
    

    要为每周创建一个线图,请转置数据框,因此列是周数,行是工作日(请注意,可以通过取消堆叠周数来避免此步骤,代替上一步中的工作日),并且拨打plot

    grid.T.plot()
    

    【讨论】:

    • 感谢您的帖子。你教会了我很多。对我不起作用的部分是绘图。我收到错误“ValueError:无法将字符串转换为浮点数:Fri”。我有一个基本的情节可以使用 plt.plot(grid.T) 但轴标签是错误的。我不明白 .groupby 命令。我遇到的问题是我的索引由不等间距的浮点数组成......我将更新问题以包含数据集。
    • 我认为同样的概念也适用于浮动索引。您只需要编写自己的方法将样本分组到组内的周期组和时间步长中。希望有帮助
    • @crewburn 我会试试的。我无法弄清楚的一件事是如何按值而不是按索引号来索引索引。假设我想获取索引值在 x 和 y 之间的所有行。
    • 如果系列/数据框被索引为问题中的示例数据,则索引值应该是浮点对象,而不是索引号。您可能想查看 groupby 方法,您传递一个函数,该函数从索引中获取一个对象,在本例中为一个浮点数,并返回一个可散列值以对行进行分组。要将浮点值分组到“桶”中,请查看numpy.digitize
    【解决方案2】:

    让我试着回答这个问题。基本上我会用完整的工作日填充或重新索引,每 5 天采样一次,同时删除由于假期或暂停而丢失的数据

    >>> coke = DataReader('KO', 'yahoo', start=datetime(2012,1,1))

    >>> startd=coke.index[0]-timedelta(coke.index[0].isoweekday()-1)

    >>> rng = array(DateRange(str(startd), periods=90))

    >>> chunk=[]

    >>> for i in range(18):

    ... chunk.append(coke[i*5:(i+1)*5].dropna())

    ...

    然后你可以循环块来绘制每周数据

    【讨论】:

    • 感谢您的回答。我无法让情节发挥作用。您如何将它们全部绘制在一起。另外,我的索引不是等距的并且是浮点类型的。我将更新我的问题以包含数据集。
    猜你喜欢
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    相关资源
    最近更新 更多