Pandas Dataframe Performance 应用函数与 shift

Posted

技术标签:

【中文标题】Pandas Dataframe Performance 应用函数与 shift【英文标题】:Pandas Dataframe Performance apply function with shift 【发布时间】:2017-12-29 21:32:04 【问题描述】:

我正在尝试优化我的代码。一个电话很快,但因为我经常遇到一些问题。

我的输入数据如下所示:

df = pd.DataFrame(data=np.random.randn(30),
                  index=pd.date_range(pd.datetime(2016,1,1), periods = 30))
df.iloc[:20] = np.nan

现在我只想应用一个简单的功能。这是我要优化的部分:

s = df >= df.shift(1)
s = s.applymap(lambda x: 1 if x else 0)

现在我有 1000 个循环,最好是 3:每个循环 1.36 毫秒。我想应该可以做得更快。不确定我是否应该矢量化,仅使用 numpy 或使用 cython。任何想法的最佳方法?我对移位运算符有点挣扎。

【问题讨论】:

不需要循环或apply,只需:(df >= df.shift(1)).dropna().astype(int) 谢谢,获得了 2 倍的改进! 1000 次循环,最好的 3 次:每个循环 776 µs 其实去掉dropna。你不需要它 【参考方案1】:

您可以将比较结果直接从bool 转换为int

(df >= df.shift(1)).astype(int)

【讨论】:

【参考方案2】:

@Paul H 的回答很好,很高效,我通常会推荐。

也就是说,如果您想榨取最后一点性能,这是numba 的一个不错的候选者,您可以使用它在一次数据传递中计算答案。

from numba import njit

@njit
def do_calc(arr):
    N = arr.shape[0]
    ans = np.empty(N, dtype=np.int_)
    ans[0] = 0
    for i in range(1, N):
        ans[i] = 1 if arr[i] > arr[i-1] else 0
    return ans

a = (df >= df.shift(1)).astype(int)
b = pd.DataFrame(pd.Series(do_calc(df[0].values), df[0].index))

from pandas.testing import assert_frame_equal
assert_frame_equal(a, b)

这里是时间

In [45]: %timeit b = pd.DataFrame(pd.Series(do_calc(df[0].values), df[0].index))
135 µs ± 1.83 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [46]: %timeit a = (df >= df.shift(1)).astype(int)
762 µs ± 22.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

【讨论】:

这似乎与使用 numpy 数组的解决方案一样快。很有意思。非常感谢您的回答!!【参考方案3】:

这是我目前最好的解决方案:

values = df.values[1:] >= df.values[:-1] 
data = np.array(values, dtype=int)
s  = pd.DataFrame(data, df.index[1:])

我得到了 10000 个循环,最好是 3 个:每个循环 125 µs。 x10 改进。但我认为它可以做得更快。

PS:此解决方案并不完全正确,因为缺少第一个零 / nan。 PPS:可以通过 pd.DataFrame(np.append([[0]],data), df.index) 进行纠正

【讨论】:

“RuntimeWarning:在更大的_equal中遇到无效值”并且输出不匹配。 你是对的,这是一个错误,因为 np.nan 与浮点数进行了比较。 Numpy 将其转换为 false。这很好,但警告仍然不好。 这是一个警告,但输出与这个答案和问题不匹配,所以它不起作用。 你说得对。现在添加了这个解决方案。它有效并且输出匹配。但是有一个警告——不是那么好。但另一方面,这只是一个警告,它仍然有效且安全。

以上是关于Pandas Dataframe Performance 应用函数与 shift的主要内容,如果未能解决你的问题,请参考以下文章

pandas.DataFrame.loc好慢,怎么遍历访问DataFrame比较快

将 Pandas Multiindexed DataFrame 与 Singleindexed Pandas DataFrame 合并

pandas.DataFrame.loc好慢,怎么遍历访问DataFrame比较快

python pandas dataframe 写入hdfs

pandas怎么选取dataframe中几列

详解pandas获取Dataframe元素值的几种方法