【问题标题】:how to pass the parameters to apply correctly如何传递参数以正确应用
【发布时间】:2018-07-10 08:43:47
【问题描述】:

有一个api函数

get_next_trading_date(exchange='SZSE', date='2017-05-01')

我有一个 DataFrame backTestRecordAfterModified 如下所示

当我跑步时

backTestRecordAfterModified['createdAt']=backTestRecordAfterModified['createdAt'].apply(func=get_next_trading_date, exchange='SZSE')

控制台显示消息:TypeError: get_next_trading_date() got multiple values for argument 'exchange'

那么,如何正确传递参数

补充

backTestRecordAfterModified['createdAt'] = backTestRecordAfterModified['createdAt'].apply(lambda date: get_next_trading_date(date, exchange='SZSE'))

上面的代码仍然显示同样的错误。

我添加get_next_trading_date的定义

我刚刚得到了最终的答案。

backTestRecordAfterModified['createdAt']=backTestRecordAfterModified['createdAt'].apply(lambda date: get_next_trading_date(date=date,exchange='SZSE'))

【问题讨论】:

  • 我认为 apply 函数需要一个元组作为 args 参数。您正在传递一个字符串作为(我认为不存在的)exchange 参数。你可以试试apply(func=get_next_trading_date, args=('SZSE'))
  • 作为替代方案,您始终可以使用 lambda 函数:apply(lambda x: get_next_trading_date(exchange="SZSE", x))
  • 您是否尝试过颠倒定义中的参数顺序? get_next_trading_date(date='2017-05-01', exchange='SZSE')
  • @jp_data_analysis ,get_next_trading_date函数是sdk提供的api,所以参数的位置是固定的。
  • @jp_data_analysis:我刚刚注意到我的第一个建议不起作用。我添加了一个工作方法的答案,使用 lambda 函数在 apply() 内部的调用中反转 get_next_trading_date() 的参数。

标签: python pandas dataframe


【解决方案1】:

您必须使用 lambda 函数将附加参数传递给 get_next_trading_date() 函数:

backTestRecordAfterModified['createdAt']=backTestRecordAfterModified['createdAt'].apply(lambda date: get_next_trading_date(date=date, exchange='SZSE'))

pandas.Series.apply() 函数实际上支持函数的附加关键字参数,但函数的第一个参数始终是 pandas 系列中的值。

如果 get_next_trading_date() 的定义不同,参数顺序颠倒:

get_next_trading_date_2(date='2017-05-01', exchange='SZSE')

你可以使用

backTestRecordAfterModified['createdAt']=backTestRecordAfterModified['createdAt'].apply(func=get_next_trading_date, exchange='SZSE').

【讨论】:

  • ,上面的代码lambda仍然显示同样的错误。
  • 这很奇怪。看来问题与this 有关。根据我之前的建议,您的情况不需要使用 lambda 函数。您的初始方法apply(func=get_next_trading_date, exchange='SZSE') 应该有效。我没有get_next_trading_date() 功能可以自己尝试。看来,这可能是一个类成员函数。您可以发布该函数的定义或代码链接吗?
  • 我已经添加了get_next_trading_date() 函数的定义,请您再看一遍。
  • 我刚刚得到了正确的解决方案。它是backTestRecordAfterModified['createdAt']=backTestRecordAfter‌​Modified['createdAt'‌​].apply(lambda date: get_next_trading_date(date=date,exchange='SZSE')) 谢谢你的帮助。
  • @inaMinute,酷!我很高兴它现在有效。我不确定我的想法是否有助于找到答案,但不客气:-)。
【解决方案2】:

对pandas系列的每个值调用apply函数,该值默认作为参数传递给函数。

您指定的附加参数在系列值之后传递。 所以在你的例子中,每次函数调用都会像

get_next_trading_date(<i-th value of the series>, exchange='SZSE')

但是在你的函数中,第一个参数是exchange,所以&lt;i-th value of the series&gt;(当前日期)被传递给exchange,然后有另一个关键字参数试图设置相同的变量。这会导致错误。 here 中的更多内容。

在这里你有两个选择。

a) 更改函数定义以将date 作为第一个参数,这样您就不必更改函数调用。但请务必在调用此函数的任何地方进行更改。

get_next_trading_date(date='2017-05-01', exchange='SZSE')

b) 更改您的函数调用以将日期作为第二个参数传递。

backTestRecordAfterModified['createdAt'] = backTestRecordAfterModified['createdAt'].apply(lambda date: get_next_trading_date(date, exchange='SZSE'))

或简化为,

backTestRecordAfterModified['createdAt'].apply(lambda date: get_next_trading_date(date, exchange='SZSE'), inplace=True)

【讨论】:

  • ,上面的代码lambda仍然显示同样的错误。
  • @inaMinute 您尝试了以上哪些更改?
  • backTestRecordAfterModified['createdAt'] = backTestRecordAfterModified['createdAt'].apply(lambda date: get_next_trading_date(date, exchange='SZSE'))
  • 我刚刚得到了正确的解决方案。它是backTestRecordAfterModified['createdAt']=backTestRecordAfterModified['createdAt'].apply(lambda date: get_next_trading_date(date=date,exchange='SZSE')),谢谢你的帮助。
【解决方案3】:

一种选择是使用df.apply 而不是series.apply

df['createdAt'] = df.apply(lambda row: get_date(row['createdAt'], 'SZSE'), axis=1)

或者,如果您不想传递整个数据框:

df['createdAt'] = [get_date(x, 'SZSE') for x in df['createdAt'].values]

【讨论】:

  • 每次都将数据帧的整行传递给函数,这不是开销吗?
  • 它没有那么漂亮,但请记住,即使apply 也只是一个隐蔽的循环。
猜你喜欢
  • 2013-03-14
  • 1970-01-01
  • 2019-03-10
  • 2018-02-10
  • 2021-11-30
  • 2022-01-26
  • 1970-01-01
相关资源
最近更新 更多