Фильтрация и создание столбца на основе столбца даты - PullRequest
0 голосов
/ 08 января 2019

У меня есть пример данных, как показано ниже:

date         Deadline
2018-08-01   
2018-08-11
2018-09-18
2018-12-08
2018-12-18

Я хочу заполнить столбец крайнего срока условиями, описанными в коде как «1 DL», «2 DL», «3 DL» и т. Д.

Создание нового столбца на основе столбца даты в python.

Это выдало ошибку:

('The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().', 'occurred at index 0')

Я пробовал, как показано ниже:

df['date'] = pd.to_datetime(df['date'], format = "%y-%m-%d").dt.date


def dead_line(df5):

    if((df5['date'] >= datetime.date(2018, 8, 1)) & (df['date'] <= datetime.date(2018, 9, 14))):

        return "1 DL"

    elif ((df5['date'] >= datetime.date(2018, 9, 15)) & (df5['date'] <= datetime.date(2018, 10, 17))):

        return "2 DL"

    elif ((df5['date'] >= datetime.date(2018, 10, 18)) & (df5['date'] <= datetime.date(2018, 12, 5))):

        return "3 DL"

    elif ((df5['date'] >= datetime.date(2018, 12, 6)) & (df5['date'] <= datetime.date(2019, 2, 1))):

        return "4 DL & EDL 2"


df['Deadline'] = df.apply(dead_line, axis = 1)

Ожидаемый результат:

date         Deadline
2018-08-01   1 DL
2018-09-16   2 DL
2018-12-07   3 DL

и т. Д.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Решение, отличное от указанного выше. Не преобразуйте ваш datetime в объект datetime для сравнения, вместо этого оставьте его как datetime64, затем примените свою функцию фильтра к другим диапазонам datetime64:

df['date'] = pd.to_datetime(df['date'], format = "%Y-%m-%d") # leaves as datetime64[ns]

print(df['date'].dtype) #datetime64[ns]


def dead_line(x):

    if (x >= pd.to_datetime('2018-08-01')) & (x <= pd.to_datetime('2018-09-14')):
        return "1 DL"
    elif (x >= pd.to_datetime('2018-09-15')) & (x <=pd.to_datetime('2018-10-17')):
        return "2 DL"
    elif (x >= pd.to_datetime('2018-10-18')) & (x <= pd.to_datetime('2018-12-05')):
        return "3 DL"
    elif (x >=pd.to_datetime('2018-12-06')) & (x <= pd.to_datetime('2019-02-01')):
        return "4 DL & EDL 2"

df['Deadline'] = df['date'].apply(dead_line) # apply your function to column, not whole df
print(df)

выход:

        date      Deadline
0 2018-08-01          1 DL
1 2018-08-11          1 DL
2 2018-09-18          2 DL
3 2018-12-08  4 DL & EDL 2
4 2018-12-18  4 DL & EDL 2
0 голосов
/ 09 января 2019

Используйте pd.cut для хранения категорий

Основная проблема заключается в том, что вы пытаетесь по столбцам выполнить операции с apply вдоль axis=1. Тем не менее, apply здесь требует построчных операций.

Тем не менее, с Pandas вам лучше использовать векторизованные операции по столбцам. Так что не используйте apply, используйте вместо этого векторизованный pd.cut. Обратите внимание, что нет необходимости прибегать к Python datetime.

# convert series to datetime
df['date'] = pd.to_datetime(df['date'])

# remember to include arbitrary lower and upper boundaries
L = ['01-01-2000', '08-01-2018', '09-14-2018', '10-17-2018',
     '12-05-2018', '02-01-2019', '01-01-2100']

# convert boundaries to datetime
dates = pd.to_datetime(L).values

# define labels for boundary ranges
labels = ['Error Lower', '1 DL', '2 DL', '3 DL', '4 DL & EDL 2', 'Error Upper']

# apply categorical binning
df['Deadline'] = pd.cut(df['date'], bins=dates, labels=labels, right=False)

print(df)

#         date      Deadline
# 0 2018-08-01          1 DL
# 1 2018-08-11          1 DL
# 2 2018-09-18          2 DL
# 3 2018-12-08  4 DL & EDL 2
# 4 2018-12-18  4 DL & EDL 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...