2013-12-06 4 views
1

Я собираю данные с нескольких станций мониторинга качества воздуха. Каждая станция должна записывать одни и те же параметры (например, O3, NO2, SO2 и т. Д.). Я мог бы помещать все в один фрейм данных, добавляя больше столбцов, но это становится неаккуратным.Усекающийся мультииндексированный информационный кадр

Имеет смысл помещать данные в мультииндексированный информационный кадр; однако я хотел бы выборочно извлечь данные (например, вытащить данные из станции «А», затем усечь в пределах указанного диапазона дат, а затем рассчитать статистику). Тем не менее, мне трудно понять, как транслировать мультииндексированный фрейм данных и начинать считать, что это невозможно. Ниже приведен примерный фреймворк, чтобы дать представление о том, с чем я имею дело.

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 

Обычно я хотел бы сделать дату мастер (и единственным) показатель, но это не представляется возможным, так как дата марка не будет уникальной (т.е. будет 2013-01-01 00:00:00 маркера для O3, NO2, SO2 и т. д. для КАЖДОГО местоположения).

Можно ли усечь через третичный индекс?
Я рассмотрел преобразование данных в сводную таблицу, но я не считаю, что это лучший путь. В этом случае мультииндексирование имеет наибольший смысл, если я могу разобраться с датой.

ответ

1

Мультииндекс имеет неявное понятие иерархии; если ваши вычисления имеют тенденцию нарушать эту иерархию, тогда вам может быть лучше не использовать мультииндекс. Что касается вашего примера, вы можете достичь того, что хотите сделать с другим порядком для индексов. То есть, если dataframe был проиндексированы ['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 
+0

На самом деле, это достаточно хорошо работает без перестановки индексов, идя один слой глубже:.. df.ix [ 'locID'] IX [ 'GasID'] IX [time1: tim2] Спасибо за помощь! – tnknepp

+0

@tnknepp вправо, но в вашем примере вы не фильтровались для «газового» типа –

+0

Моя вина, я не собирался оставлять этот бит. Спасибо еще раз за помощь. – tnknepp

0

Самый простой/быстрый - это, вероятно, выбрать даты, необходимые для агрегации.

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] 
Смежные вопросы