2013-09-12 3 views
4

У меня есть DF, который имеет две даты, представляющие интерес, который выглядит вроде как:Создать dataframe панды с количеством предметов, охватывающих диапазон дат

LIST_DATE  END_DATE 
2000-04-18 2000-05-17 00:00:00 
2000-05-18 2000-09-18 00:00:00 
2000-04-18 2001-06-07 00:00:00 

И я создал индекс периода таблицы «montot» по месяцам что в настоящее время только месяц и год индекс

<class 'pandas.tseries.period.PeriodIndex'> 
freq: M 
[1999-01, ..., 2013-07] 

То, что я хочу сделать, это для каждого месяца во второй таблице «montot» сосчитать элементы в 1-й таблице, которые попадают в периоды времени (случается активные объявления по месяцам) и добавьте это поле в таблицу ... так, например, 1-й элемент в 1-й стол будет считаться 1 в 4-м месяце и один раз в месяц 5, а второй пункт будет засчитан один раз в месяц 5-месячный 9-й и т. д. с ежемесячной суммой, записанной в новой таблице/поле. Так что я буду иметь таблицу

Month active 
1/1999  5 
2/1999  8 

и т.д .. У вас нет понятия, как подойти к нему с панды/Python ...

ответ

6

Вот один из способов сделать это, сначала value_counts в периоды в каждом из столбцов дат (с использованием метода to_period Timestamp):

In [11]: p = pd.PeriodIndex(freq='m', start='2000-1', periods=18) 

In [12]: starts = df['LIST_DATE'].apply(lambda t: t.to_period(freq='m')).value_counts() 

In [13]: ends = df['END_DATE'].apply(lambda t: t.to_period(freq='m')).value_counts() 

переиндексации это по PeriodIndex, заполнить в NaNs (так что вы можете вычитать) и принять кумулятивный начался с го е кумулятивный состава, чтобы дать вам активный в данный момент:

In [14]: starts.reindex(p).fillna(0).cumsum() - ends.reindex(p).fillna(0).cumsum() 
Out[14]: 
2000-01 0 
2000-02 0 
2000-03 0 
2000-04 2 
2000-05 2 
2000-06 2 
2000-07 2 
2000-08 2 
2000-09 1 
2000-10 1 
2000-11 1 
2000-12 1 
2001-01 1 
2001-02 1 
2001-03 1 
2001-04 1 
2001-05 1 
2001-06 0 
Freq: M, dtype: float64 

Альтернативой Последним шагом является создание DataFrame (который изначально отслеживает изменения, следовательно, начинает положительно и заканчивается отрицательным):

In [21]: current = pd.DataFrame({'starts': starts, 'ends': -ends}, p) 

In [22]: current 
Out[22]: 
     ends starts 
2000-01 NaN  NaN 
2000-02 NaN  NaN 
2000-03 NaN  NaN 
2000-04 NaN  2 
2000-05 -1  1 
2000-06 NaN  NaN 
2000-07 NaN  NaN 
2000-08 NaN  NaN 
2000-09 -1  NaN 
2000-10 NaN  NaN 
2000-11 NaN  NaN 
2000-12 NaN  NaN 
2001-01 NaN  NaN 
2001-02 NaN  NaN 
2001-03 NaN  NaN 
2001-04 NaN  NaN 
2001-05 NaN  NaN 
2001-06 -1  NaN 

In [23]: current.fillna(0) 
Out[23]: 
     ends starts 
2000-01  0  0 
2000-02  0  0 
2000-03  0  0 
2000-04  0  2 
2000-05 -1  1 
2000-06  0  0 
2000-07  0  0 
2000-08  0  0 
2000-09 -1  0 
2000-10  0  0 
2000-11  0  0 
2000-12  0  0 
2001-01  0  0 
2001-02  0  0 
2001-03  0  0 
2001-04  0  0 
2001-05  0  0 
2001-06 -1  0 

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

In [24]: current.fillna(0).cumsum() 
Out[24]: 
     ends starts 
2000-01  0  0 
2000-02  0  0 
2000-03  0  0 
2000-04  0  2 
2000-05 -1  3 
2000-06 -1  3 
2000-07 -1  3 
2000-08 -1  3 
2000-09 -2  3 
2000-10 -2  3 
2000-11 -2  3 
2000-12 -2  3 
2001-01 -2  3 
2001-02 -2  3 
2001-03 -2  3 
2001-04 -2  3 
2001-05 -2  3 
2001-06 -3  3 

и суммированием этих столбцов вместе, дает тем, в настоящее время активен, и тот же результат, что и выше:

In [25]: current.fillna(0).cumsum().sum(1) 
+0

Примечание: Это правдоподобно вы можете .shift() конец даты здесь (прежде чем fillna) ... –

+0

Свист назад TOTD – Jeff

+0

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

Смежные вопросы