我试图在我的polars DataFrame中为所有窗口计算窗口和静态数组之间的点积,我正在努力找出正确的方法来做到这一点。这里有人对我有任何提示吗?这里是一个快速工作的例子:
import polars as pl
import numpy as np
dummy_data = {
"id_": [1, 2, 3, 4, 5, 6, 7, 8],
"value": [1, 1, 2, 2, 3, 3, 4, 4]
}
const = np.array([.5, .5])
df_ = pl.DataFrame(dummy_data)
df_ = df_.set_sorted("id_")
# This panics: Cannot apply operation on arrays of different lengths
df_.rolling("id_", period="2i").agg(pl.col("value").dot(pl.lit(const)))
expected = {
"id_": [1, 2, 3, 4, 5, 6, 7, 8],
"value": [None, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0]
}
字符串
我所期望的是在上面的例子中发生以下计算:
np.dot([1.0, 1.0], const)
np.dot([1.0, 2.0], const)
np.dot([2.0, 2.0], const)
etc.
型
大概这不工作,因为第一个窗口只有1个值,而不是2?至少这是什么,它似乎对我来说。任何人都有一个更好的方法来做到这一点?
3条答案
按热度按时间x4shl7ld1#
在收到一些答案后,找到了我自己的答案,我想分享一些基准。
以下是问题的3种可能解决方案(通过添加一个组列,稍微调整以提供对问题的更全面的了解):
数据类型:
字符串
在极地不和的牧场有礼貌:
型
rolling
礼貌@迪恩麦格雷戈:型
shift
,这是我提出的解决方案:型
每一个都提供了完全相同的答案。下面是几个不同大小的数据集上每一个的计算时间:
型
如果其他人需要运行类似的计算,希望这些数字是有用的。正确的选择取决于所使用的数据和代码的可读性。
fd3cxomn2#
你有几个问题要解决。第一个,你已经发现了,第一个窗口只有1个值而不是2。你可以通过稍后移动
dot
操作来解决这个问题,这样你就可以进行过滤。你还将遇到一个问题,即const
如何不作为pl.lit(const)
进行广播,或者mul
如何不对列表进行操作。为了解决这个问题,您需要添加列来表示行索引和const
。从那里您可以分解value
和const
列。完成后,你没有任何列表列,可以执行普通的group_by/agg来让点工作。要得到你想要的最终结果,你需要将所有这些都连接到原始框架中(减去要替换的值列)。字符串
hgqdbh6s3#
我不能说我完全理解为什么下面的工作-它几乎看起来像一个Polars错误?因为你的
const
是相同的两个元素,下面的工作。个字符
似乎
pl.col("value").dot(0.5)
通过pl.col("value")
“广播”了0.5
。如果我用pl.Series([0.5, 0.5])
替换0.5
,那么我得到PanicException: Cannot apply operation on arrays of different lengths
。这对我来说毫无意义,所以我假设Polars中有一个bug。