我有一个函数,可以根据条件将numpy数组转换为包含True或False的数组,然后将相邻的True或False条目分组,并计算每组的长度,这是为了确定给定月份降雨量数据中干旱期或潮湿期的长度。
这是一个函数:
import itertools
def spell(X, kind='wet', how='mean', threshold=0.5):
if kind=='wet':
condition = X>threshold
else:
condition = X<=threshold
length = [sum(1 if x==True else nan for x in group) for key,group in itertools.groupby(condition) if key]
if not length:
res = 0
elif how=='mean':
res = np.mean(length)
else:
res = np.max(length)
return res
因此,基本上有一个选项来确定平均长度或最大长度的湿或干期给定一个numpy数组的降水数据与默认参数设置为平均长度的湿期。
我对Pandas使用这个函数,将它应用到历史记录的每个月:
#Create example dataframe
np.random.seed(1324)
idx = pd.DatetimeIndex(start='1960-01-01', periods=100, freq='d')
values = np.random.random(100)
df = pd.DataFrame(values, index=idx)
#Apply function
df.resample('M', how=spell)
我得到的是
0
1960-01-31 1.555556
1960-02-29 1.500000
1960-03-31 1.777778
1960-04-30 6.000000
很完美,但是我希望能够动态地更改此函数的默认值,以便可以使用df的其他选项。resample()。我已经研究了functools.partial()
,但是这只是输入参数显式设置的情况下的解决方案,即spell(kind='dry', how='max', threshold=0.7)
。有没有办法改变函数的默认参数,而不需要在后面显式地设置它们,这样我就可以在df.resample()
中使用它了?
3条答案
按热度按时间0sgqnhkj1#
函数的默认值存储在该函数的
func_defaults
属性中,该属性是与函数的func_code.co_varnames
元组的 trailing 元素配对的值的元组。例如:您甚至可以在事后给予参数一个默认值:
警告:我曾想过(ab)使用
mock
库来允许临时覆盖函数默认值,类似于recent answer of mine,然而,它似乎在之后将默认值设置为None
,这意味着mock
中存在bug(或者我误解了它的行为),或者像这样弄乱函数有点危险。手动保存和恢复默认值似乎工作正常,不过,正如您所期望的那样。
vhmi4jdf2#
这听起来像是函数 Package 器的工作!
可以使用以下命令调用此函数
它将返回一个
spell
函数的 Package 版本,该函数使用新参数作为“默认值”,而不是在函数定义中创建的参数。vsdwdz233#
实际上,你可以使用partial函数来修改默认的关键字参数,这样就不需要在以后显式地设置它们了。诀窍是将原始函数设置为等于结果partial函数。
partial的一般示例
定义我们的泛型函数
使用partial覆盖函数签名(这两行是唯一重要的部分)
一个二个一个一个
要重置默认值,您可以重复调用partial
或者您可以像这样修改分部函数的关键字字典
要恢复为原始kwargs,可以将变量覆盖为.func中的原始函数地址
在原始问题中实施部分
显示函数“spell”的正常使用
一个12b1x一个13b1x
使用functools部分函数更新拼写kwargs
使用函数工具与编辑__默认值__
在使用已导入的函数时,functools partial方法也很有用,因为模块中的函数不具有与当前python脚本中描述的函数类似的__defaults__函数
因为我们定义了originalFunction,所以可以使用.defaults访问默认的kwargs
x一个铝16块x一个铝17块x一个铝18块x一个铝19块x
此方法不适用于导入的模块,如np.array
所以我们可以使用partial函数来更新np.数组kwargs
一个22个1个23个1个1个24个1个1个1个25个1个1个
使用functools与在kwargs上传递
可以将args和kwargs传递给另一个函数,而不使用partial
x一个26块1 x一个27块1 x
我们可以将传入的参数和kwarg传递给另一个函数,同时使用以下方法覆盖defaultValue kwarg
一个28块一个
这种方法的一个缺点是,您不能使用这个新函数签名来覆盖原始函数!
如果这样做,它将创建一个无限循环
一个32b1x一个33b1x