Вернуть определенные строки в столбец на основе двух переданных дат, используя оператор if или лямбда-функцию.

Я хотел бы вернуть определенные строки из двух переданных столбцов даты. Мой код до сих пор:

df_Date = df[df['state'].str.contains('Traded Away') & df['maturity_date']!=0][['state','maturity_date']]
df_Date['maturity_date'] = pd.to_datetime(df_Date['maturity_date'])
df_Date['Today'] = pd.to_datetime('today') 
df_Date['Days'] = (df_Date['maturity_date'] - df_Date['Today'])
print(df_Date.head(10))


          state maturity_date      Today       Days
0   Traded Away    2018-03-15 2018-03-19    -4 days
10  Traded Away    2025-06-15 2018-03-19  2645 days
12  Traded Away    2047-03-21 2018-03-19 10594 days
15  Traded Away    2166-03-15 2018-03-19 54052 days
17  Traded Away    2166-12-18 2018-03-19 54330 days
20  Traded Away    2023-05-04 2018-03-19  1872 days
22  Traded Away    2027-11-15 2018-03-19  3528 days
23  Traded Away    2025-03-15 2018-03-19  2553 days
25  Traded Away    2023-01-15 2018-03-19  1763 days
26  Traded Away    2166-05-01 2018-03-19 54099 days

Моя функция для преобразования дней в строки выглядит следующим образом и выдает ошибку: TypeError: недопустимое сравнение типов при печати фрейма данных.

def Risk_Bucket(x): 
    if x  <= 730:
        return '< 2YR'
    elif  (x > 730 and x  <= 1825):
        return '2YR_5YR'
    elif  (x > 1825 and x  <= 2555):
        return '5YR_7YR'
    elif  (x > 2555 and x <= 3650):
        return '7YR_10YR'
    elif  (x > 3650 and x  <= 7300):
        return '10YR_20YR'
    elif  (x > 7300):
        return '> 20YR'
    else:
        return "Check passed Date"
df_Date['Bucket'] = Risk_Bucket(df_Date['Days'])

print(df_Date.head(10))

Я предполагаю, что это из-за того, что в столбцах «Дни» есть строка «дни»?

Как сделать столбец «Дни» числовым? Любые предложения, чтобы решить эту проблему и улучшить мой код?


person Peter Lucas    schedule 19.03.2018    source источник
comment
Связано: Python: преобразование timedelta в int в кадре данных   -  person jpp    schedule 19.03.2018


Ответы (1)


Я считаю, что вам нужно преобразовать timedeltas или дни с помощью days :

df_Date['Bucket'] = df_Date['Days'].dt.days.apply(Risk_Bucket)

Улучшенный код с cut:

bins = [-np.inf,730,1825,2555,3650,7300,np.inf]
labels = ['< 2YR', '2YR_5YR','5YR_7YR','7YR_10YR', '10YR_20YR', '> 20YR']
df_Date['Bucket'] = pd.cut(df_Date['Days'].dt.days, bins=bins, labels=labels)

Проверять:

bins = [-np.inf,730,1825,2555,3650,7300,np.inf]
labels = ['< 2YR', '2YR_5YR','5YR_7YR','7YR_10YR', '10YR_20YR', '> 20YR']
df_Date['Bucket'] = df_Date['Days'].dt.days.apply(Risk_Bucket)
df_Date['Bucket1'] = pd.cut(df_Date['Days'].dt.days, bins=bins, labels=labels)
print (df_Date)
          state maturity_date       Today       Days    Bucket   Bucket1
0   Traded Away    2018-03-15  2018-03-19    -4 days     < 2YR     < 2YR
10  Traded Away    2025-06-15  2018-03-19    72 days     < 2YR     < 2YR
12  Traded Away    2047-03-21  2018-03-19 10594 days    > 20YR    > 20YR
15  Traded Away    2166-03-15  2018-03-19 54052 days    > 20YR    > 20YR
17  Traded Away    2166-12-18  2018-03-19 54330 days    > 20YR    > 20YR
20  Traded Away    2023-05-04  2018-03-19  1872 days   5YR_7YR   5YR_7YR
22  Traded Away    2027-11-15  2018-03-19  3528 days  7YR_10YR  7YR_10YR
23  Traded Away    2025-03-15  2018-03-19  2553 days   5YR_7YR   5YR_7YR
25  Traded Away    2023-01-15  2018-03-19  1763 days   2YR_5YR   2YR_5YR
26  Traded Away    2166-05-01  2018-03-19 54099 days    > 20YR    > 20YR
person jezrael    schedule 19.03.2018
comment
Спасибо, Израэль... еще раз; ) dt.days преобразует значения в целые числа? - person Peter Lucas; 19.03.2018
comment
@PeterLucas - Точно, но здесь cut лучше. - person jezrael; 19.03.2018
comment
Привет, @jezrael, я получаю сообщение об ошибке SettingWithCopyWarning (значение пытается быть установлено для копии фрагмента из DataFrame). После прочтения многочисленных сообщений я подумал, что df_Date = df_Date.copy() удалит предупреждение? - person Peter Lucas; 20.03.2018
comment
@PeterLucas - Можете ли вы показать код, в котором вы получаете предупреждение? Также это предупреждение немного запутано, поэтому нужно также проверить код выше - 1,2 строки. Явно есть какая-то фильтрация, значит нужно copy, вы правы. например df1 = df[df['state'].isin(['Traded Away','another value'])].copy() - person jezrael; 20.03.2018
comment
Хм, вторая строка должна быть dfRFQ_Breakdown_By_State.loc[mask, 'rbc_security_type1'] = dfRFQ_Breakdown_By_State.loc[mask, 'instrument_group'].str.upper() - фильтрация в обе стороны. - person jezrael; 20.03.2018
comment
Я проследил его до моего исходного кадра данных: по критериям со значением в другом столбце. Вышеупомянутое разделение затем используется в этом обновленном фрейме данных. - person Peter Lucas; 20.03.2018
comment
Давайте продолжим обсуждение в чате. - person Peter Lucas; 20.03.2018