2014-01-04 3 views
4

Хотя это прямолинейно и легко нарисовать объекты groupby в пандах, мне интересно, какой самый питонический (pandastic?) Способ захватить уникальные группы из объекта groupby. Например: Я работаю с атмосферными данными и стараюсь строить суточные тенденции в течение нескольких дней или более. Ниже приводится DataFrame, содержащая много дней на сумму данных, где временные метки индекс:Построение с GroupBy в Pandas/Python

<class 'pandas.core.frame.DataFrame'> 
DatetimeIndex: 10909 entries, 2013-08-04 12:01:00 to 2013-08-13 17:43:00 
Data columns (total 17 columns): 
Date  10909 non-null values 
Flags 10909 non-null values 
Time  10909 non-null values 
convt 10909 non-null values 
hino  10909 non-null values 
hinox 10909 non-null values 
intt  10909 non-null values 
no  10909 non-null values 
nox  10909 non-null values 
ozonf 10909 non-null values 
pmtt  10909 non-null values 
pmtv  10909 non-null values 
pres  10909 non-null values 
rctt  10909 non-null values 
smplf 10909 non-null values 
stamp 10909 non-null values 
no2  10909 non-null values 
dtypes: datetime64[ns](1), float64(11), int64(2), object(3) 

Чтобы иметь возможность усреднять (и принимать другие статистические данные) данные на каждую минуту в течение нескольких дней, я группировать dataframe: data = no.groupby('Time')

можно затем легко заговор означает отсутствие концентрации, а также квартили:

ax = figure(figsize=(12,8)).add_subplot(111) 
title('Diurnal Profile for NO, NO2, and NOx: East St. Louis Air Quality Study') 
ylabel('Concentration [ppb]') 
data.no.mean().plot(ax=ax, style='b', label='Mean') 
data.no.apply(lambda x: percentile(x, 25)).plot(ax=ax, style='r', label='25%') 
data.no.apply(lambda x: percentile(x, 75)).plot(ax=ax, style='r', label='75%') 

Вопрос, который подпитывает мой вопрос, что для того, чтобы построить более интересные вещи, выглядящие как участки с использованием как fill_between() необходимо знать информацию о х-оси согласно документации

fill_between(x, y1, y2=0, where=None, interpolate=False, hold=None, **kwargs) 

Для жизни меня, я не могу понять, лучший способ сделать это. Я пробовал:

  1. Итерации над объектом GroupBy и создавая массив групп
  2. захватывая все уникальные записи Время от оригинального DataFrame

я могу сделать эти работы, но я знаете, что есть лучший способ. Python слишком красив. Любые идеи/подсказки?

ОБНОВЛЕНИЕ: Статистические данные могут быть сброшены в новую dataframe использованием unstack(), таких как

no_new = no.groupby('Time')['no'].describe().unstack() 
no_new.info() 
<class 'pandas.core.frame.DataFrame'> 
Index: 1440 entries, 00:00 to 23:59 
Data columns (total 8 columns): 
count 1440 non-null values 
mean  1440 non-null values 
std  1440 non-null values 
min  1440 non-null values 
25%  1440 non-null values 
50%  1440 non-null values 
75%  1440 non-null values 
max  1440 non-null values 
dtypes: float64(8) 

Хотя я должен быть в состоянии построить с помощью fill_between()no_new.index, я получаю TypeError.

Текущий код участка и TypeError:

ax = figure(figzise=(12,8)).add_subplot(111) 
ax.plot(no_new['mean']) 
ax.fill_between(no_new.index, no_new['mean'], no_new['75%'], alpha=.5, facecolor='green') 

TypeError:

TypeError         Traceback (most recent call last) 
<ipython-input-6-47493de920f1> in <module>() 
     2 ax = figure(figsize=(12,8)).add_subplot(111) 
     3 ax.plot(no_new['mean']) 
----> 4 ax.fill_between(no_new.index, no_new['mean'], no_new['75%'], alpha=.5,  facecolor='green') 
     5 #title('Diurnal Profile for NO, NO2, and NOx: East St. Louis Air Quality Study') 
     6 #ylabel('Concentration [ppb]') 

C:\Users\David\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\axes.pyc in fill_between(self, x, y1, y2, where, interpolate, **kwargs) 
    6986 
    6987   # Convert the arrays so we can work with them 
-> 6988   x = ma.masked_invalid(self.convert_xunits(x)) 
    6989   y1 = ma.masked_invalid(self.convert_yunits(y1)) 
    6990   y2 = ma.masked_invalid(self.convert_yunits(y2)) 

C:\Users\David\AppData\Local\Enthought\Canopy\User\lib\site-packages\numpy\ma\core.pyc in masked_invalid(a, copy) 
    2237   cls = type(a) 
    2238  else: 
-> 2239   condition = ~(np.isfinite(a)) 
    2240   cls = MaskedArray 
    2241  result = a.view(cls) 

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' 

Сюжет, как сейчас выглядит следующим образом: enter image description here

+0

Heck, что выглядит довольно хорошо для меня ... ааа теперь я думаю, что я вижу, , вам нужно назначить объект графика переменной, тогда вы можете захватить ось ... – dartdog

ответ

5

Сохранение статистики GroupBy (средний/25/75) в качестве столбцов в новом фрейме данных, а затем передают index нового регистрационного кадра как параметр xplt.fill_between() работает для меня (тестируется с помощью matplotlib 1.3.1). например,

gdf = df.groupby('Time')[col].describe().unstack() 
plt.fill_between(gdf.index, gdf['25%'], gdf['75%'], alpha=.5) 

gdf.info() должен выглядеть следующим образом:

<class 'pandas.core.frame.DataFrame'> 
Index: 12 entries, 00:00:00 to 22:00:00 
Data columns (total 8 columns): 
count 12 non-null float64 
mean  12 non-null float64 
std  12 non-null float64 
min  12 non-null float64 
25%  12 non-null float64 
50%  12 non-null float64 
75%  12 non-null float64 
max  12 non-null float64 
dtypes: float64(8) 

Update: для решения TypeError: ufunc 'isfinite' not supported исключения, необходимо сначала преобразовать Time столбец из серии строковых объектов в "HH: MM" формат серии datetime.time объектов, что может быть сделано следующим образом:

df['Time'] = df.Time.map(lambda x: pd.datetools.parse(x).time()) 
+0

Удивительный! Это отличное начало. Я продолжаю получать ошибку типа при попытке fill_between(). Похоже, что у него возникают проблемы с преобразованием значений оси x? Быстрый google показал, что это была ошибка в matplotlib v. 1.3.0, поэтому я обновился до 1.3.1, но не кубиками. Есть идеи? Точная ошибка: TypeError: ufunc 'isfinite' не поддерживается для типов ввода, и входы не могут быть безопасно принуждены к любым поддерживаемым типам в соответствии с правилом литья '' safe '' –

+0

Какую версию панд вы используете? Я думаю, что я тестировал 0.12 и мастер – Garrett

+0

Статистика: Pandas (0.12.0), Numpy (1.8.0), Python (2.7.3 64bit) –