Ретроспективно минимальные рабочие дни с сегодняшнего дня до следующей даты в другом столбце для разных кодов - PullRequest
0 голосов
/ 10 октября 2018

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

date matdate code 2-Jan-2018 5-Jan-2018 A 3-Jan-2018 6-Jan-2018 A 8-Jan-2018 12-Jan-2018 B 10-Jan-2018 15-Jan-2018 A 11-Jan-2018 16-Jan-2018 B 15-Jan-2018 17-Jan-2018 A И я ищу вывод в следующем формате - который принимает все выходные дни недели в выводе (ниже также может бытьв сводном формате, но в качестве индекса должны быть указаны все дни недели)

date matdate code BusinessDaysToNextMat 2-Jan-2018 5-Jan-2018 A 3 2-Jan 2018 B 0 3-Jan-2018 8-Jan-2018 A 2 3-Jan-2018 B 0 4-Jan-2018 A 1 4-Jan-2018 B 0 5-Jan-2018 A 0 5-Jan-2018 B 0 8-Jan-2018 A 0 8-Jan-2018 17-Jan-2018 B 7 9-Jan-2018 A 0 9-Jan-2018 B 6 10-Jan-2018 16-Jan-2018 A 4 10-Jan-2018 B 6 11-Jan-2018 A 3 11-Jan-2018 16-Jan-2018 B 3 12-Jan-2018 A 4 12-Jan-2018 B 2 15-Jan-2018 17-Jan-2018 A 1 15-Jan-2018 B 1

Большое спасибо за просмотр!

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

вот что я делаю в настоящее время, что, очевидно, не является наиболее эффективным:

# Step1: Make a new df with data of just one code and fill up any blank matdates with the very first available matdate. After that:
temp_df['newmatdate'] = datetime.date(2014,1,1) # create a temp column to hold the current minimum maturity date
temp_df['BusinessDaysToNextMat'] = 0 # this is the column that we are after

mindates = [] # initiate a list to maintain any new maturity dates which come up and keep it min-sorted
mindates.append(dummy) # where dummy is the very first available maturity date (as of 1st date we only know one trade, which is this) Have written dummy here, but it is a longer code, which may not pertain here
x = mindates[0] # create a variable to be used in the loop

g = datetime.datetime.now()
for i in range(len(temp_df['matdate'])): # loop through every date
    if np.in1d(temp_df['matdate'][i],mindates)[0]==False: # if the current maturity date found DOES NOT exist in the list of mindates, add it
        mindates.append(temp_df['matdate'][i])
    while min(mindates)< temp_df['date'][i]: # if the current date is greater than the min mindate held so far, 
        mindates.sort() # sort it so you are sure to remove the min mindate
        x = mindates[0] # note the date which you are dropping before dropping it
        del mindates[0] # drop the curr min mindate, so the next mindate, becomes the new min mindate
    if temp_df['matdate'][i] != x: # I think this might be redundant, but it is basically checking if the new matdate which you may be adding, wasn't the one
        mindates.append(temp_df['matdate'][i]) # which you just removed, if not, add this new one to the list
    curr_min = min(mindates)
    temp_df['newmatdate'][i] = curr_min # add the current min mindate to the column

h = datetime.datetime.now()
print('loop took '+str((h-g).seconds) + ' seconds')

date = [d.date() for d in temp_df['date']] # convert from 'date' to 'datetime' to be able to use np.busday_count()
newmatdate = [d.date() for d in temp_df['newmatdate']]
temp_df['BusinessDaysToNextMat'] = np.busday_count(date,newmatdate) # phew

Также это только для одного кода - и затем я зациклю его на всех кодах

0 голосов
/ 10 октября 2018

Вы можете использовать numpy.busday_count , чтобы добиться этого: импортируйте numpy как np

df['BusinessDaysToNextMat'] = df[['date', 'matdate']].apply(lambda x: np.busday_count(*x), axis=1)
df

#        date    matdate code  BusinessDaysToNextMat
#0 2018-01-01 2018-01-05    A                      4
#1 2018-01-03 2018-01-06    A                      3
#2 2018-01-08 2018-01-12    B                      4
#3 2018-01-10 2018-01-15    A                      3
#4 2018-01-11 2018-01-16    B                      3
#5 2018-01-15 2018-01-17    A                      2
#6 2018-01-20 2018-01-22    A                      0

Это не совсем то, что вы имели в своем примере, но больше всего:

index = pd.MultiIndex.from_product(
        [pd.date_range(
                df['date'].min(),
                df['date'].max(), freq='C').values,
         df['code'].unique()],
                names = ['date', 'code'])

resampled = pd.DataFrame(index=index).reset_index().merge(df, on=['date', 'code'], how='left')

calc = resampled.dropna()
calc['BusinessDaysToNextMat'] = calc[['date', 'matdate']].apply(lambda x: np.busday_count(*x), axis=1)
final = resampled.merge(calc, on=['date', 'code', 'matdate'], how='left')
final['BusinessDaysToNextMat'].fillna(0, inplace=True)

final
#         date code    matdate  BusinessDaysToNextMat
#0  2018-01-02    A 2018-01-05                    3.0
#1  2018-01-02    B        NaT                    0.0
#2  2018-01-03    A 2018-01-06                    3.0
#3  2018-01-03    B        NaT                    0.0
#4  2018-01-04    A        NaT                    0.0
#5  2018-01-04    B        NaT                    0.0
#6  2018-01-05    A        NaT                    0.0
#7  2018-01-05    B        NaT                    0.0
#8  2018-01-08    A        NaT                    0.0
#9  2018-01-08    B 2018-01-12                    4.0
#10 2018-01-09    A        NaT                    0.0
#11 2018-01-09    B        NaT                    0.0
#12 2018-01-10    A 2018-01-15                    3.0
#13 2018-01-10    B        NaT                    0.0
#14 2018-01-11    A        NaT                    0.0
#15 2018-01-11    B 2018-01-16                    3.0
#16 2018-01-12    A        NaT                    0.0
#17 2018-01-12    B        NaT                    0.0
#18 2018-01-15    A 2018-01-17                    2.0
#19 2018-01-15    B        NaT                    0.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...