Pandas - применить функцию к кадру данных с несколькими аргументами из разных столбцов - PullRequest
1 голос
/ 08 марта 2020

Я хотел бы использовать функцию apply () для фрейма данных для генерации диапазона дат благодаря функции pandas date_range ().

Следующий код работает и выполняет то, что я ожидаю.

import pandas as pd

def my_date_range(start, end, freq):
    return pd.date_range(start = start, end = end, freq = freq)

df = pd.DataFrame({'Start':[pd.Timestamp('1970-01-02 00:00:00')], 'End':[pd.Timestamp('1970-01-02 00:30:00')], 'Freq':[pd.Timedelta(5,'m')]})

df1 = df.apply(lambda x: my_date_range(x.Start, x.End, x.Freq), axis=1)

Результат:

In [28]: df
Out[28]: 
       Start                 End     Freq
0 1970-01-02 1970-01-02 00:30:00 00:05:00

In[29] : df1[0]
Out[29]: 
DatetimeIndex(['1970-01-02 00:00:00', '1970-01-02 00:05:00',
               '1970-01-02 00:10:00', '1970-01-02 00:15:00',
               '1970-01-02 00:20:00', '1970-01-02 00:25:00',
               '1970-01-02 00:30:00'],
              dtype='datetime64[ns]', freq='5T')

Итак, теперь моя проблема / мои вопросы. Я мог бы прочитать, что таким образом можно использовать apply () без лямбды, как я понимаю:

df2 = df[['Start', 'End', 'Freq']].apply(my_date_range, axis=1)

Но приведенный выше код выдает следующую ошибку.

TypeError: ("my_date_range() missing 2 required positional arguments: 'end' and 'freq'", 'occurred at index 0')

Пожалуйста, что я делаю не так?

И интересно ли избегать использования лямбды? (лучшие показатели?)

Наконец, есть ли способ использовать напрямую pd.date_range?

Если я попытаюсь использовать приведенный ниже код, я получаю следующую ошибку:

df1 = df.apply(lambda x: pd.date_range(x.Start, x.End, x.Freq), axis=1)

"periods must be a number, got {periods}".format(periods=periods)

TypeError: ('periods must be a number, got 0 days 00:05:00', 'occurred at index 0')

Заранее спасибо за помощь! Хорошего дня!

Ответы [ 2 ]

1 голос
/ 08 марта 2020

1

Как видно из сообщения об ошибке, если вы хотите использовать имя функции для pandas.DataFrame.apply, функция должна принять pandas.Series в качестве аргумента. Так и должно быть.

def my_date_range(x):
    return pd.date_range(start = x.Start, end = x.End, freq = x.Freq)
df2 = df.apply(my_date_range, axis=1)

2

Ну, лично я думаю, что лямбда делает вещи намного удобнее. В вашем случае, оригинальный способ определения функции с последующим использованием другой лямбды совсем не удобен, поскольку точка lambda не обязывает использовать def. Однако вы можете использовать лямбду и сделать ее более удобной, как вы пытались в последней части вопроса.

3

Причина ошибки заключается в том, что функция pd.date_range arguments выглядит следующим образом , pandas.date_range(start=None, end=None, periods=None, ...) Так что, если вы просто дадите ему как позиционный аргумент, как вы это сделали, он подумает, что третий аргумент - period=. Вы должны указать его в качестве аргумента ключевого слова (как вы делали это выше).

df1 = df.apply(lambda x: pd.date_range(start = x.Start, end = x.End, freq = x.Freq), axis=1)
0 голосов
/ 08 марта 2020

Как насчет этого:

import pandas as pd
start = pd.Timestamp('1970-01-02 00:00:00')
end = pd.Timestamp('1970-01-02 00:30:00')
pd.date_range(start, end, freq='5Min')
...