截断多索引数据帧

时间:2013-12-06 19:02:55

标签: python-2.7 pandas

我从几个空气质量监测站提取数据。每个站应记录相同的参数(例如O3,NO2,SO2等)。我可以通过添加更多列将所有内容放入一个数据框中,但这变得草率。

将数据放入多索引数据帧是有意义的;但是,我想有选择地提取数据(例如从工作站提取数据" A"然后在指定的日期范围内截断,然后计算统计数据)。但是,我很难弄清楚如何整理多索引数据帧并开始相信它是不可能的。下面发布的是一个示例数据框,用于了解我正在处理的内容。

import pandas as pd
import numpy as np

dates = pd.date_range('20130101',periods=3,freq='5s')
dates = dates.append(dates)

locations = list('AAABBB')
gascode = ['no2','o3','so2']*2

tup = pd.MultiIndex.from_tuples( zip(locations,gascode,dates), names=['Location','gas','Date'] )

data = pd.DataFrame(data=range(6),index=tup,columns=['val1'])

>>> data

Location gas Date                  val1         
A        no2 2013-01-01 00:00:00     0
         o3  2013-01-01 00:00:05     1
         so2 2013-01-01 00:00:10     2
B        no2 2013-01-01 00:00:00     3
         o3  2013-01-01 00:00:05     4
         so2 2013-01-01 00:00:10     5

通常我会将日期作为主(和唯一)索引,但这是不可行的,因为日期戳不会是唯一的(即O3,NO2将有2013-01-01 00:00:00标记,每个位置的SO2等)。

是否可以通过三级索引进行截断? 我已经考虑过将数据转换为数据透视表,但我认为这不是最佳选择。在这种情况下,多索引最有意义,如果我可以解决日期问题。

2 个答案:

答案 0 :(得分:1)

最简单/最快可能是在聚合之前选择所需的日期。

In [19]: data
Out[19]: 
                                  val1
Location gas Date                     
A        no2 2013-01-01 00:00:00     0
         o3  2013-01-01 00:00:05     1
         so2 2013-01-01 00:00:10     2
B        no2 2013-01-01 00:00:00     3
         o3  2013-01-01 00:00:05     4
         so2 2013-01-01 00:00:10     5

[6 rows x 1 columns]

In [20]: x = data.reset_index()

In [21]: x[(x.Date > '20130101 00:00:00') & (x.Date < '20130101 00:00:10')].set_index(data.index.names)
Out[21]: 
                                  val1
Location gas Date                     
A        o3  2013-01-01 00:00:05     1
B        o3  2013-01-01 00:00:05     4

[2 rows x 1 columns]

答案 1 :(得分:1)

多指数具有隐含的层次概念;如果你的计算倾向于破坏这种层次结构,那么最好不要使用多索引。至于您的示例,您可以使用不同的索引顺序来实现您想要做的事情。也就是说,如果数据框由['Location','Date','gas'](按此顺序)索引

                                  val1
Location Date                gas      
A        2013-01-01 00:00:00 no2     0
         2013-01-01 00:00:05 o3      1
         2013-01-01 00:00:10 so2     2
B        2013-01-01 00:00:00 no2     3
         2013-01-01 00:00:05 o3      4
         2013-01-01 00:00:10 so2     5

您可以使用ix,如下所示:

df.ix[ 'A' ].ix[ pd.Timestamp( '2013-01-01 00:00:05' ):pd.Timestamp( '2013-01-01 00:00:10' )]

输出:

                         val1
Date                gas      
2013-01-01 00:00:05 o3      1
2013-01-01 00:00:10 so2     2

或单列:

df.val1[ 'A' ][ pd.Timestamp( '2013-01-01 00:00:05' ):pd.Timestamp( '2013-01-01 00:00:10' )]

输出:

Date                 gas
2013-01-01 00:00:05  o3     1
2013-01-01 00:00:10  so2    2
Name: val1, dtype: int64