2015-06-14 138 views
0

我有一个非常尴尬的数据帧,看起来像这样:绘制一个尴尬的大熊猫多指数数据帧

+----+------+-------+-------+--------+----+--------+ 
| |  | hour1 | hour2 | hour 3 | … | hour24 | 
+----+------+-------+-------+--------+----+--------+ 
| id | date |  |  |  | |  | 
| 1 | 3 |  4 |  0 |  96 | 88 |  35 | 
| | 4 | 10 |  2 |  54 | 42 |  37 | 
| | 5 |  9 | 32 |  8 | 70 |  34 | 
| | 6 | 36 | 89 |  69 | 46 |  78 | 
| 2 | 5 | 17 | 41 |  48 | 45 |  71 | 
| | 6 | 50 | 66 |  82 | 72 |  59 | 
| | 7 | 14 | 24 |  55 | 20 |  89 | 
| | 8 | 76 | 36 |  13 | 14 |  21 | 
| 3 | 5 | 97 | 19 |  41 | 61 |  72 | 
| | 6 | 22 |  4 |  56 | 82 |  15 | 
| | 7 | 17 | 57 |  30 | 63 |  88 | 
| | 8 | 83 | 43 |  35 | 8 |  4 | 
+----+------+-------+-------+--------+----+--------+ 

对于每个id存在的dates列表,并为每个date小时列是整天的价值数据在整个24小时内按小时分解。

我想要做的是绘制(使用matplotlib)每个ids的完整小时数据,但我想不出一种方法来做到这一点。我正在研究创建numpy矩阵的可能性,但我不确定这是否是正确的路径。

澄清:基本上,对于每个ID我想将所有小时数据按顺序连接在一起并绘制。我已经有了适当的日子,所以我想这只是一个问题,找到一种方法将每个id的所有每小时数据放入一个对象中

有关如何最好地完成此任务的任何想法?

这里是CSV格式一些示例数据:http://www.sharecsv.com/s/e56364930ddb3d04dec6994904b05cc6/test1.csv

+0

你怎么想情节呢?你是说你想将DataFrame的每一行作为单独的一行来绘制,并将所有这些行组合在一个图中? – BrenBarn

+0

@BrenBarn本质上,对于每个ID,我想将所有小时数据按顺序连接在一起并绘制出来。我已经有了适当的日子,所以我想这只是一个问题,找到一种方法将每个id的所有每小时数据放入一个对象中。 – metersk

+0

再次,请说出你的意思是“绘制”。绘制它*如何*?吧情节?线情节?每个栏/行代表什么?如果有的话,这些裸露/线条如何组合成一张图?你的意思是说,例如,对于id = 1,你会得到96分(因为它有四个日期,每个24分)? – BrenBarn

回答

2

下面是一个方法:

for groupID, data in d.groupby(level='id'): 
    fig = pyplot.figure() 
    ax = fig.gca() 
    ax.plot(data.values.ravel()) 
    ax.set_xticks(np.arange(len(data))*24) 
    ax.set_xticklabels(data.index.get_level_values('date')) 

ravel是一个numpy的方法,该方法将多个行串出成一个长一维数组。

当心在大型数据集上交互式地运行它,因为它会为每一行创建一个单独的图。如果要保存绘图等,请设置一个非交互式matplotlib后端,并使用savefig来保存每个图形,然后在创建下一个图形之前将其关闭。

2

堆叠数据框可能会让您感兴趣,因此您可以将日期和时间放在同一个索引中。例如,做

df = df.stack().unstack(0) 

将日期和时间放在索引和id作为列名称。调用df.plot()将为您提供同一轴上每个时间序列的线图。所以,你可以做到这一点作为

ax = df.stack().unstack(0).plot() 

,要么通过传递参数给plot方法或通过调用ax方法格式化轴。

+0

太棒了,谢谢你。 – metersk

+0

不客气。我认为它解决了'尴尬的数据框'问题 – JoeCondron

1

我对这个解决方案并不满意,但也许它可以作为出发点。由于你的数据是循环的,我选择了一个极坐标图。不幸的是,y方向上的分辨率很差。因此,我手动缩放成积:

import pandas as pd 
import numpy as np 
from matplotlib import pyplot as plt 

df = pd.read_csv('test1.csv') 
df_new = df.set_index(['id','date']) 
n = len(df_new.columns) 

# convert from hours to rad 
angle = np.linspace(0,2*np.pi,n) 


# color palete to cycle through 
n_data = len(df_new.T.columns) 
color = plt.cm.Paired(np.linspace(0,1,n_data/2)) # divided by two since you have 'red', and 'blue' 
from itertools import cycle 
c_iter = cycle(color) 

fig = plt.figure() 
ax = fig.add_subplot(111, polar=True) 

# looping through the columns and manually select one category 
for ind, i in enumerate(df_new.T.columns): 
    if i[0] == 'red': 
     ax.plot(angle,df_new.T[i].values,color=c_iter.next(),label=i,linewidth=2) 


# set the labels 
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False)) 
ax.set_xticklabels(range(24)) 

# make the legend 
ax.legend(loc='upper left', bbox_to_anchor = (1.2,1.1)) 
plt.show() 

放大0:

enter image description here

变焦1: enter image description here

放大2: enter image description here

+1

这与我所寻找的有很大不同,但这仍然真的非常棒。 – metersk

+1

小心如果你复制粘贴代码,我只是删除了y-log-scale – Moritz

+0

我很好奇,这些数据代表什么? – Moritz