Как получить данные за весь день из индекса, соответствующего одному дню

У меня есть фрейм данных df1, индексированный по дате и времени с записями каждые минуты в течение нескольких недель:

           SAMPLE_TIME       Bottom     Top      Out     state                                                                    
0  2015-07-15 16:41:56      48.625   55.812   43.875        1       
1  2015-07-15 16:42:55      48.750   55.812   43.875        1     
2  2015-07-15 16:43:55      48.937   55.812   43.875        1       
3  2015-07-15 16:44:56      49.125   55.812   43.812        1      
4  2015-07-15 16:45:55      49.312   55.812   43.812        1     

Я хочу найти день с самым низким средним значением (TempBottom, TempTop), а затем получить данные за весь день по минутам, чтобы я мог построить этот день, я пробовал:

df2 = df1.groupby(pd.TimeGrouper('D')).agg(min) \
.sort(['TempTop','TempBottom'], ascending=[True,True])

Что дает мне самую низкую температуру в дни заказанных. образец:

SAMPLE_TIME       Bottom     Top      Out     state                                                                    
2015-10-17       19.994   25.840   21.875        0       
2015-08-29       26.182   28.777   25.937        0       
2015-11-19       19.244   33.027   28.937        0        
2015-11-07       19.744   33.527   28.125        0           

тогда я подумал, что все, что мне нужно, это взять индекс первой записи из df2:

 df1[df2.index[1]]

Но я получаю сообщение об ошибке:

KeyError: Timestamp('2015-08-29 00:00:00')

person InsaneBot    schedule 10.12.2015    source источник


Ответы (2)


Из документов:

Предупреждение

Следующий выбор поднимет KeyError; в противном случае эта методология выбора будет несовместима с другими методами выбора в пандах (поскольку это не срез и он не разрешается в один)

dft['2013-1-15 12:30:00']

Чтобы выбрать одну строку, используйте .loc

In [71]: dft.loc['2013-1-15 12:30:00']
Out[71]: 
A    0.193284
Name: 2013-01-15 12:30:00, dtype: float64

Итак, вам нужно использовать метод loc в вашем случае:

In [103]: df1.loc[df2.index[0]]
Out[103]: 
           SAMPLE_TIME  TempBottom  TempTop  TempOut  State  Bypass
2015-07-15    16:41:56      48.625   55.812   43.875      1       1
2015-07-15    16:42:55      48.750   55.812   43.875      1       1
2015-07-15    16:43:55      48.937   55.812   43.875      1       1
2015-07-15    16:44:56      49.125   55.812   43.812      1       1
2015-07-15    16:45:55      49.312   55.812   43.812      1       1

ИЗМЕНИТЬ

Когда вы передаете единственный аргумент, он пытается получить доступ с помощью метки. Однако, когда вы проходите интервал, он используется как срез. Вы можете сделать трюк, чтобы передать значение + 1 день:

In [276]: df2.index[0]
Out[276]: Timestamp('2015-07-15 00:00:00', offset='D')

In [277]: df2.index[0] + 1
Out[277]: Timestamp('2015-07-16 00:00:00', offset='D')

In [278]: df1.loc[df2.index[0]: df2.index[0] + 1]
Out[278]: 
                     TempBottom  TempTop  TempOut  State  Bypass
SAMPLE_TIME                                                     
2015-07-15 16:41:56      48.625   55.812   43.875      1       1
2015-07-15 16:42:55      48.750   55.812   43.875      1       1
2015-07-15 16:43:55      48.937   55.812   43.875      1       1
2015-07-15 16:44:56      49.125   55.812   43.812      1       1
2015-07-15 16:45:55      49.312   55.812   43.812      1       1

ИЗМЕНИТЬ2

Или вы можете преобразовать date из Timestamp в str:

In [355]: df2.index[0]
Out[355]: Timestamp('2015-07-15 00:00:00', offset='D')

In [356]: df2.index[0].date()
Out[356]: datetime.date(2015, 7, 15)

In [357]: str(df2.index[0].date())
Out[357]: '2015-07-15'

In [359]: df1[str(df2.index[0].date())]
Out[359]: 
                     TempBottom  TempTop  TempOut  State  Bypass
2015-07-15 16:41:56      48.625   55.812   43.875      1       1
2015-07-15 16:42:55      48.750   55.812   43.875      1       1
2015-07-15 16:43:55      48.937   55.812   43.875      1       1
2015-07-15 16:44:56      49.125   55.812   43.812      1       1
2015-07-15 16:45:55      49.312   55.812   43.812      1       1
person Anton Protopopov    schedule 10.12.2015
comment
Я попробовал ваше решение, но вместо этого получил это KeyError: 'the label [2015-11-04 00:00:00] is not in the [index]' - person InsaneBot; 10.12.2015
comment
Однако это работает df1.loc['2015-11-04'] проблема заключается в дополнительной точности (времени), которая включена в индекс - person InsaneBot; 10.12.2015
comment
Вам нужно сохранить свой индекс в df1 как дату и время, или вы можете преобразовать его в дату? Если бы вы могли преобразовать его в дату, вы могли бы использовать df1.loc[df2.index[0].date()] - person Anton Protopopov; 10.12.2015
comment
Я думаю, что мы используем разные версии Python: df2.index[0] + 1 выдает эту ошибку ValueError: Cannot add integral value to Timestamp without offset. - person InsaneBot; 11.12.2015
comment
при выполнении: df1.loc[df2.index[0].date()] выдает эту ошибку KeyError: 'the label [2015-11-04] is not in the [index]' - person InsaneBot; 11.12.2015
comment
Наконец-то я нашел несколько модифицированный способ сделать это, используя df1.loc[df2.index[4].strftime('%Y-%m-%d')] (см. мой ответ), но я чувствую, что это очень хакерский - person InsaneBot; 11.12.2015

Итак, вот мой мыслительный процесс в сочетании с ответом @Anton Protopopov:

In [1]: df1.ix[df2]
# call trace
ValueError: Cannot index with multidimensional key

In [2]: df1.ix[df2.index]
out[2]:
SAMPLE_TIME       Bottom     Top      Out     state                                                                    
2015-10-17          NaN      NaN      NaN      NaN        
2015-08-29          NaN      NaN      NaN      NaN         
2015-11-19          NaN      NaN      NaN      NaN        
2015-11-07          NaN      NaN      NaN      NaN         

In [3]: df1.ix[df2.index[4:5]]
Out[3]: 
SAMPLE_TIME       Bottom     Top      Out     state                                                                    
2015-11-04           NaN      NaN      NaN      NaN     

In [33]: df1.loc[df2.index[4:5]]
KeyError: "None of [DatetimeIndex(['2015-11-04'], dtype='datetime64[ns]', name=u'SAMPLE_TIME', freq=None, tz=None)] are in the [index]"

В конце концов я отказался от ix и решил заставить loc работать, как Anton рекомендовал попробовать:

In [4]: df1.loc[df2.index[0].date()]
KeyError: 'the label [2015-11-04] is not in the [index]'

Я подумал, что loc принимает только строки, которые, наконец, сработали:

In [5]: df1.loc[df2.index[4].strftime('%Y-%m-%d')]
Out[5]: 
SAMPLE_TIME              Bottom     Top      Out     state                                                                    
2015-11-04 00:00:22      56.256   56.300   43.750        0     
2015-11-04 00:01:22      56.256   56.300   43.812        0      
2015-11-04 00:02:22      56.256   56.300   43.812        0       
2015-11-04 00:03:22      56.256   56.300   43.812        0     
person InsaneBot    schedule 11.12.2015
comment
Вы можете выполнить функцию str для преобразования date в str с помощью str(df2.index[4].date()), что, на мой взгляд, проще, чем strftime. Кстати, какие версии python и pandas вы используете? Я использую 3.4.3 и 0.17.1. - person Anton Protopopov; 11.12.2015