Rom*_*rés 9 python performance pandas pandas-groupby
我需要对一个 DataFrame 进行分组,并在每个组上应用多个链式函数。
\n我的问题与 pandas 基本相同- Groupby 两个函数:cumsum
然后应用于shift
每个组。
那里有关于如何获得正确结果的答案,但它们的性能似乎不太理想。因此,我的具体问题是:是否有比我下面描述的方法更有效的方法?
\n首先是一些大的测试数据:
\nfrom string import ascii_lowercase\n\nimport numpy as np\nimport pandas as pd\n\n\nn = 100_000_000\nnp.random.seed(0)\ndf = pd.DataFrame(\n {\n "x": np.random.choice(np.array([*ascii_lowercase]), size=n),\n "y": np.random.normal(size=n),\n }\n)\n
Run Code Online (Sandbox Code Playgroud)\n下面是各个功能的性能:
\n%timeit df.groupby("x")["y"].cumsum()\n4.65 s \xc2\xb1 71 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n%timeit df.groupby("x")["y"].shift()\n5.29 s \xc2\xb1 54.1 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n
Run Code Online (Sandbox Code Playgroud)\n一个基本的解决方案是分组两次。这似乎不是最理想的,因为分组占总运行时间的很大一部分,并且应该只进行一次。
\n%timeit df.groupby("x")["y"].cumsum().groupby(df["x"]).shift()\n10.1 s \xc2\xb1 63.5 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n
Run Code Online (Sandbox Code Playgroud)\n上述问题的公认答案建议使用apply
自定义函数来避免此问题。然而由于某种原因,它的性能实际上比以前的解决方案差得多。
def cumsum_shift(s):\n return s.cumsum().shift()\n\n%timeit df.groupby("x")["y"].apply(cumsum_shift)\n27.8 s \xc2\xb1 858 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n
Run Code Online (Sandbox Code Playgroud)\n您知道如何优化这段代码吗?特别是在我想要链接两个以上函数的情况下,性能提升可能会变得非常显着。
\n让我知道这是否有帮助,几周前我遇到了同样的问题。
\n我只是通过拆分代码解决了这个问题。并创建一个单独的 groupby 对象,其中包含有关组的信息。
\n# creating groupby object\ng = df.groupby('x')['y']\n\n%timeit g.cumsum()\n592 ms \xc2\xb1 8.67 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n\n%timeit g.shift()\n1.7 s \xc2\xb1 8.68 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
826 次 |
最近记录: |