1

在大熊猫数据帧上使用 IX 时,我注意到一些奇怪的行为。

当我在同一数据帧上连续调用 .ix 50 次时,它的运行速度比我在 50 个不同数据帧上调用 .ix 时快 10 倍。

.ix 的幕后是否有缓存?我注意到底部循环使我的内存使用量增加了一倍。为什么内存会增加?

有没有办法修改这种行为?

请注意,如果您直接使用 numpy,它在两种情况下都在 7.4 秒内运行,内存增加为 0,这就是让我相信 pandas 正在缓存的原因。

显然,您永远不想在每​​个单独的元素上调用 .ix ......

import pandas as pd
import numpy as np
import datetime as dt
print 'pandas', pd.__version__

li_list = []
for i in range(50):
    li_list.append(pd.DataFrame(data=np.random.randn(50, 17000)))

print 'starting'

dt_start = dt.datetime.now()
a = 0
for i in range(50):
    b = li_list[0] #Only access first element
    for j in b.columns:
        a += b.ix[i, j]
print (dt.datetime.now()-dt_start).total_seconds()


dt_start = dt.datetime.now()
a = 0
for i in range(50):
    b = li_list[i] #Access all in list
    for j in b.columns:
        a += b.ix[i, j]
print (dt.datetime.now()-dt_start).total_seconds()

输出:

pandas 0.9.1
starting
3.651
22.009
4

2 回答 2

2

是的,ix缓存结果。b.ix返回一个_NDFrameIndexer。它的__getitem__方法调用DataFrame的get_value方法,后者调用_get_item_cache方法,缓存结果。

缓存也可以解释为什么访问第一个 DataFrame 50 次比访问 50 个 DataFrame 更快。

于 2012-12-03T22:19:23.307 回答
1

注意:第一次在轴索引中查找位置时,有一个哈希表填充步骤。这可能就是您在此处看到的内容,并且会因使用而变得模糊timeit(因为哈希表只计算一次、存储并重用)。还解释了增加的内存使用量。

在熊猫的未来版本中,我计划使用简单的顺序轴索引来提高此类代码在简单数据上的性能。我将在 GitHub 问题跟踪器上记录您的用例。

https://github.com/pydata/pandas/issues/2420

于 2012-12-03T23:06:00.443 回答