熊猫-将函数应用于具有来自不同列的多个参数的数据框

时间:2020-03-08 16:50:48

标签: python pandas apply

由于熊猫date_range()函数,我想对数据框使用apply()函数来生成日期范围。

以下代码可以正常工作,并且可以完成我期望的工作。

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')

所以现在我的问题/我的问题。 据我了解,我可以读到有可能以这种方式在没有lambda的情况下使用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')

请,我在做什么错了?

避免使用lambda有趣吗? (更好的表演?)

最后,还有一种直接使用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 个答案:

答案 0 :(得分:1)

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使事情变得更加方便。在您的情况下,用于定义一个函数然后使用另一个lambda的原始方式根本不方便,因为lambda的要点不必使用def。但是,您可以使用lambda并使它在问题的最后一部分中更加方便。

3

错误的原因是因为函数pd.date_range的参数是这样的。 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)

答案 1 :(得分:0)

那这样的事情呢?

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')