2015-05-23 5 views
1

Я хочу выбрать данные из фреймворка данных за конкретный день года. Вот что я имею в качестве минимального примера.python pandas time series select day of year

import pandas as pd 
from datetime import datetime 
from datetime import timedelta 
import numpy.random as npr 
rng = pd.date_range('1/1/1990', periods=365*10, freq='D') 
df1 = pd.DataFrame(npr.randn(len(rng)), index=rng) 
print df1 

Это создает:

    0 
1990-01-01 -0.032601 
1990-01-02 -0.496401 
1990-01-03 0.444490 

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

td = timedelta(days=31) 
dr = pd.date_range(datetime(1990,12,31)+td,datetime(2000,12,31), 
        freq=pd.DateOffset(months=12, days=0)) 
print dr 

Это, конечно, порождает:

DatetimeIndex(['1991-01-31', '1992-01-31', '1993-01-31', '1994-01-31', 
       '1995-01-31', '1996-01-31', '1997-01-31', '1998-01-31', 
       '1999-01-31', '2000-01-31'], 
dtype='datetime64[ns]', freq='<DateOffset: kwds={'months': 12, 'days': 0}>', tz=None) 

При попытке разрезать dataframe по списку дат, сгенерировать ошибку:

monthly_df1 = df1[dr] 

Выход:

KeyError: "['1991-01-30T16:00:00.000000000-0800' '1992-01-30T16:00:00.000000000-0800'\n 
'1993-01-30T16:00:00.000000000-0800' '1994-01-30T16:00:00.000000000-0800'\n 
'1995-01-30T16:00:00.000000000-0800' '1996-01-30T16:00:00.000000000-0800'\n 
'1997-01-30T16:00:00.000000000-0800' '1998-01-30T16:00:00.000000000-0800'\n 
'1999-01-30T16:00:00.000000000-0800' '2000-01-30T16:00:00.000000000-0800'] 
not in index" 

Я думаю, что у меня есть две забавы Основные проблемы здесь: (1) существует лучший способ извлечения годовых данных за конкретную дату; и (2) временные ряды в списке dataframe и date_range отличаются. Я был бы признателен за информацию по обеим проблемам. Спасибо, сообщество.

+0

Я планирую манипулировать DataFrame – marathonman4202

+0

ли не 'df1 [(df1.index.month = = 1) & (df1.index.day == 31)] 'работает для вас в этом случае? – Zero

+0

Я думаю, что маска будет работать, но я хотел бы иметь возможность корректировать к дню года (целое число от 1 до 365 или 366). Это позволяет мне использовать его внутри процедуры оптимизации. – marathonman4202

ответ

3

Вы можете использовать .ix для фильтрации dr даты от df1

In [107]: df1.ix[dr] 
Out[107]: 
        0 
1991-01-31 -1.239096 
1992-01-31 0.153730 
1993-01-31 -0.685778 
1994-01-31 0.132170 
1995-01-31 0.154965 
1996-01-31 1.800437 
1997-01-31 2.725209 
1998-01-31 -0.084751 
1999-01-31 1.604511 
2000-01-31  NaN 

Even df1.loc[dr] работ.


Кроме того, в этом случае, вы можете просто передать эти условия для извлечения даты

In [108]: df1[(df1.index.month==1) & (df1.index.day==31)] 
Out[108]: 
        0 
1990-01-31 -0.362652 
1991-01-31 -1.239096 
1992-01-31 0.153730 
1993-01-31 -0.685778 
1994-01-31 0.132170 
1995-01-31 0.154965 
1996-01-31 1.800437 
1997-01-31 2.725209 
1998-01-31 -0.084751 
1999-01-31 1.604511 
+0

Обе эти работы для моего оригинального сообщения. По какой-то причине только второй работает для проблемы в моем реальном коде (хотя и не в произвольный день года).Возможно, мне нужно написать небольшую функцию для генерации параметров маски для произвольного дня года. – marathonman4202

+0

Спасибо @JohnGalt. Это действительно работает, и достаточно легко создать маску с чем-то вроде datetime.datetime (year, 1, 1) + datetime.timedelta (days - 1) (см. [Сообщение здесь] (http: // stackoverflow. com/questions/2427555/python-question-year-and-day-of-year-to-date)) – marathonman4202

1

Самый простой метод, который можно использовать, чтобы получить данные в год с частичной строки индексации, то resample ежегодно

df1['1990-12-31':].resample('A', how='first') 

строка нарезка описана в документации панд под 17.4.1 DatetimeIndex Частичное струнный Indexing. С помощью этого метода вы можете вырезать создание timedelta, второй date_range и сложную и ошибочную нарезку. Метод resample является стандартным, используя «A» в качестве знака для «годовой» частоты и как = «первым», чтобы просто захватить первый соответствующий элемент.

  0 
1990-12-31 -0.600904 
1991-12-31 -1.083462 
1992-12-31 0.469949 
1993-12-31 -0.809852 
1994-12-31 -0.165877 
1995-12-31 1.460035 
1996-12-31 -0.332960 
1997-12-31 -0.140873 
1998-12-31 1.088687 
1999-12-31 0.190218 

Check out the pandas documentation, смотрите в 17.4.1 DatetimeIndex Частичное Строка Indexing Here is the TimeSeries documentation mentioning resampling И, наконец, метод the API doc for the resample()

+0

Ах, не отвечает, о чем попросил ОП. – Zero

+1

Неужели @John Galt (1) есть лучший способ извлечения ежегодных данных для определенной даты? Да, с индексацией частичной строки, описанной выше, и (2) временные ряды в списке dataframe и date_range отличаются. Я был бы признателен за информацию по обеим проблемам. Мой метод избегает обеих проблем. – OYRM

+0

Может быть, вы правы, я оставлю это на OP =) на боковой ноте, индекс года - хорошая находка, я не знал о ее существовании, спасибо. – Zero