【问题标题】:Pandas DataFrame.apply going very slow for scipy.statsPandas DataFrame.apply 对于 scipy.stats 的速度非常慢
【发布时间】:2019-04-10 01:41:54
【问题描述】:

我正在尝试创建一个将返回的自定义 DataFrame.describe() 函数

  • numpy 统计数据
  • scipy 统计数据
  • 来自某些来源的分位数

这应该会重现我的问题

# Python 3.6.6, Pandas 0.22.0

import pandas as pd
import numpy as np
import scipy.stats as sc

d = pd.DataFrame(np.random.randint(0,10, size=100000))
d.apply(np.mean) #Works
d.apply(np.std) #Works
d.apply(sc.kurtosis) #Works
d.apply([np.mean, np.std]) #Works
d.apply([np.mean, sc.kurtosis]) # Gets stuck

如果我包含 scipy 函数,它将永远运行,但如果我只使用 numpy.如果有更好的方法可以使用我自己的统计输出自定义列表来模拟 pd.DataFrame.describe() 的输出,我也愿意接受。

【问题讨论】:

  • 你的意思是sc.stats.kurtosis?另外,什么版本的熊猫?据我所知pd.DataFrame.apply 不接受函数列表。
  • 是的,我愿意。我正在使用更新版本的熊猫,这可能是它接受列表的原因,因为我的代码运行没有错误。我在上面更新以反映您的。
  • 您在使用列表推导时是否发现与我的解决方案相同的问题?
  • 您的解决方案运行良好。现在唯一的问题是我可能可以配置的输出。我现在看到 np.mean 返回一个 float64 而 sc.kurtosis 返回一个 1 元素数组。我怀疑这与我的方法的问题有关。
  • 可能,我怀疑您可以通过检索单元素数组来操纵输出。它没有回答您关于 apply 的问题,但我们知道一般 apply 很慢,即使在倒数第二个情况下也是如此。

标签: python pandas numpy dataframe scipy


【解决方案1】:

pd.DataFrame.apply 不是魔法。它只是一个 Python 级别的循环和一种方便的方法。除了这里,它并没有增加太多的便利。它也不接受列表,因为它沿轴应用单个函数,因此您的代码是错误的。

您可以直接将您的数据框作为参数提供给所有这些函数,这表现出一致的性能:

# Python 3.6.0, Pandas 0.19.2

import pandas as pd
import numpy as np
import scipy as sc

np.random.seed(0)
d = pd.DataFrame(np.random.randint(0,10, size=10**6))

%timeit np.mean(d)                                          # 1.3 ms per loop
%timeit np.std(d)                                           # 2.82 ms per loop
%timeit sc.stats.kurtosis(d)                                # 33 ms per loop
%timeit [func(d) for func in (np.mean, np.std)]             # 3.95 ms per loop
%timeit [func(d) for func in (np.mean, sc.stats.kurtosis)]  # 34.8 ms per loop

【讨论】:

  • 我想我可以通过对输出进行一些操作来获得我想要的结果。谢谢。
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 2016-10-10
  • 2012-11-05
相关资源
最近更新 更多