Python: используйте функцию в лямбда-выражении pandas

У меня есть следующий код, пытающийся найти час столбца «Даты» во фрейме данных:

print(df['Dates'].head(3))
df['hour'] = df.apply(lambda x: find_hour(x['Dates']), axis=1)

def find_hour(self, input):
    return input[11:13].astype(float)

где print(df['Dates'].head(3)) выглядит так:

0    2015-05-13 23:53:00
1    2015-05-13 23:53:00
2    2015-05-13 23:33:00

Однако я получил следующую ошибку:

    df['hour'] = df.apply(lambda x: find_hour(x['Dates']), axis=1)
NameError: ("global name 'find_hour' is not defined", u'occurred at index 0')

Кто-нибудь знает, что я пропустил? Спасибо!


Обратите внимание, что если я помещу функцию непосредственно в строку лямбда, как показано ниже, все будет работать нормально:

df['hour'] = df.apply(lambda x: x['Dates'][11:13], axis=1).astype(float)

person Edamame    schedule 01.04.2016    source источник
comment
Вы также можете извлечь час непосредственно из x, если это объект даты и времени, и что должно быть?   -  person Padraic Cunningham    schedule 01.04.2016


Ответы (2)


Вы пытаетесь использовать find_hour до того, как он будет определен. Вам просто нужно поменять местами:

def find_hour(self, input):
    return input[11:13].astype(float)

print(df['Dates'].head(3))
df['hour'] = df.apply(lambda x: find_hour(x['Dates']), axis=1)

Правка: Падраик указал на очень важный момент: find_hour() определяется как принимающее два аргумента, self и input, но вы указываете только один. Вы должны определить find_hour() как def find_hour(input):, за исключением того, что определение аргумента как input затеняет встроенную функцию. Вы можете подумать о том, чтобы переименовать его во что-то более описательное.

person zondo    schedule 01.04.2016

что не так со старым добрым .dt.hour?

In [202]: df
Out[202]:
                 Date
0 2015-05-13 23:53:00
1 2015-05-13 23:53:00
2 2015-05-13 23:33:00

In [217]: df['hour'] = df.Date.dt.hour

In [218]: df
Out[218]:
                 Date  hour
0 2015-05-13 23:53:00    23
1 2015-05-13 23:53:00    23
2 2015-05-13 23:33:00    23

и если ваш столбец Date имеет строковый тип, вы можете преобразовать его в дату и время first:

df.Date = pd.to_datetime(df.Date)

или просто:

df['hour'] = int(df.Date.str[11:13])
person MaxU    schedule 01.04.2016