Возврат нескольких столбцов на основе диапазона дат с использованием панд - PullRequest
0 голосов
/ 10 декабря 2018

Я в основном пытаюсь рассчитать доход на сегодняшний день, используя панд.Я хотел бы вернуть N столбцов, состоящих из каждого конца квартала.Каждый столбец будет рассчитывать общий доход на дату на конец квартала.У меня есть:

df['Amortization_per_Day'] = (2.5, 3.2, 5.5, 6.5, 9.2)
df['Start_Date'] = ('1/1/2018', '2/27/2018', '3/31/2018', '5/23/2018', '6/30/2018') 
Date_Range = pd.date_range('10/31/2017', periods=75, freq='Q-Jan')

и я хочу сделать что-то вроде:

df['Amortization_per_Day'] * (('Date_Range' - df['Start_Date']).dt.days + 1)

для каждой даты в пределах Date_Range.Я не уверен, как передать Date_Range через функцию и вернуть N столбцов.Я читал о zip (* df) и shift, но не до конца понял.Большое спасибо за вашу помощь.

1 Ответ

0 голосов
/ 10 декабря 2018

Решение

Вот полное решение:

from datetime import datetime
import pandas as pd

df = pd.DataFrame()
df['Amortization_per_Day'] = (2.5, 3.2, 5.5, 6.5, 9.2)
df['Start_Date'] = ('1/1/18', '2/27/18', '3/31/18', '5/23/2018', '6/30/2018') 
df['Start_Date'] = pd.to_datetime(df['Start_Date'])
dr = pd.date_range('10/31/2017', periods=75, freq='Q-Jan')

def betweendates(x, y):
    xv = x.values.astype('datetime64[D]')
    xpad = np.zeros(xv.size + 2, dtype=xv.dtype)
    xpad[1:-1] = xv
    xpad[0],xpad[-1] = np.datetime64(datetime.min), np.datetime64(datetime.max)

    yv = y.values.astype('datetime64[D]')

    return (xpad[:-1] <= yv[:,None]) & (xpad[1:] >= yv[:,None])

# get a boolean array that indicates which dates in dr are in between which dates in df['Start_Date']
btwn = betweendates(df['Start_Date'], dr)

# based on the boolean array btwn, select out the salient rows from df and dates from dr
dfsel = df[btwn[:, 1:].T]
drsel = dr[btwn[:, 1:].sum(axis=1, dtype=bool)]

# do the actual calculation the OP wanted
dfsel['Amortization_per_Day'] * ((drsel - dfsel['Start_Date']).dt.days + 1)

Вывод:

0       77.5
2      170.5
4      294.4
4     1140.8
4     1987.2
4     2806.0
4     3652.4
4     4498.8
4     5345.2
4     6173.2
      ...   
4    52394.0
4    53212.8
4    54059.2
4    54905.6
4    55752.0
4    56570.8
4    57417.2
4    58263.6
4    59110.0
4    59938.0
Length: 74, dtype: float64

Объяснение

Логический массив btwn выглядит следующим образомthis:

[[ True False False False False False]
 [False  True False False False False]
 [False False False  True False False]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 ...

i -ая строка btwn соответствует i -ому периоду времени в вашем диапазоне дат.В каждой строке ровно одно значение будет True, а остальные - False.Значение True в 0-м столбце указывает, что дата-время предшествует любому из Start_Times, значение True в 1-м столбце указывает, что дата-время находится между 0 -ым и1 даты в Start_Times и т. д.Значение True в последнем столбце указывает на то, что дата и время идут после любого из Start_Times.

Путем нарезки btwn следующим образом:

btwn[:, 1:]

его можно использовать длясопоставьте время в вашем диапазоне дат с предшествующим Start_Time.Если вместо этого вы измените срезы btwn так:

btwn[:, :-1]

, вы в конечном итоге сопоставите каждую дату и время с Start_Time.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...