我需要将 python 脚本转换为 ruby。我使用 gems Pandas 和 Numpy 使工作变得非常简单。
例如我有这样的台词:
# python
# DF is a dataframe from Pandas
DF['VAL'].ewm(span = vDAY).mean()
DF['VOLAT'].rolling(vDAY).std()
所以没有问题,我这样转换:
# ruby
df['VAL'].ewm(span: vDAY).mean
df['VOLAT'].rolling(vDAY).std
简单。
但是我有一个来自 Pandas 的函数
apply
,它接受一个函数作为第一个参数,我真的不知道如何在 ruby 中转换它。
是这样的:
# python
import numpy as np
DF['VAL'].rolling(vDAY).apply(lambda x: np.polyfit(range(len(x)), x, 1)[0])
# output=> NaN or Float
我尝试像这样分解 lambda:
# ruby
polyfit = ->(x) { t = Numpy.polyfit((0...x.size).to_a, x, 1); t[0] }
puts polyfit.call(<insert Array argument>)
#=> I have a satisfying output for my lambda
# but...
df['VAL'].rolling(vDAY).apply(&polyfit)
# output=> `apply': <class 'TypeError'>: must be real number, not NoneType (PyCall::PyError)
# or
df['VAL'].rolling(vDAY).apply{ |x| polyfit.call(x) }
# output=> `apply': <class 'TypeError'>: apply() missing 1 required positional argument: 'func' (PyCall::PyError)
# or
df['VAL'].rolling(vDAY).apply(polyfit)
#output=> `apply': <class 'TypeError'>: must be real number, not NoneType (PyCall::PyError)
# or
df['VAL'].rolling(vDAY).apply(:polyfit)
# output=> `apply': <class 'TypeError'>: 'str' object is not callable (PyCall::PyError)
这显然不起作用。问题是 python 内联语法中的“x”参数,我真的不知道如何“以 ruby 方式”获取它
如果有人可以将这个
apply
函数从 python 语法“翻译”为 ruby,那就太好了:)
我只是想指出,我是一名 ruby/rails 开发人员,从专业角度来说我不懂 python。
更新:
好吧,这对我来说是对Python代码的完全误解:
apply
需要一个函数参数作为可调用对象。所以在 ruby 中,我需要的不是 lambda 而是 Proc。
所以遇到同样问题的人的解决方案:
# ruby
polyfit = Proc.new { t = Numpy.polyfit((0...x.size).to_a, x, 1); t[0] }
df['VAL'].rolling(vDAY).apply(polyfit)
解决方案是使用
Proc
(请参阅原始问题中的“更新”部分)
# ruby
polyfit = Proc.new { t = Numpy.polyfit((0...x.size).to_a, x, 1); t[0] }
df['VAL'].rolling(vDAY).apply(polyfit)
如果有人可以将这个
函数从python语法“翻译”为ruby,那就太好了apply
等效的 Ruby 语法是:
DF['VAL'].rolling(vDAY).apply(-> x { np.polyfit(range(len(x)), x, 1)[0] })