在大型pandas数据帧上使用IX时,我注意到了一些奇怪的行为。
当我连续50次在相同的数据帧上调用.ix时,它比我在50个不同的数据帧上调用.ix的速度快10倍。
.ix上的幕后是否有缓存?我注意到底部循环使我的内存使用量加倍。为什么记忆会增加?
有没有办法修改这种行为?
请注意,如果你使用直接numpy,它会在7.4秒内运行,两个情况下内存增加0,这让我相信大熊猫正在缓存。
显然你永远不想在每个元素上调用.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
答案 0 :(得分:2)
是的,ix
缓存结果。 b.ix
会返回_NDFrameIndexer
。其__getitem__
方法调用DataFrame的get_value
方法,该方法调用_get_item_cache
方法,该方法可缓存结果。
缓存还可以解释为什么访问第一个DataFrame 50次比从50个DataFrame访问要快。
答案 1 :(得分:1)
注意:第一次在轴索引中查找位置时,会有一个哈希表填充步骤。这可能就是你在这里看到的并且会被timeit
所掩盖(因为哈希表是计算一次,存储和重用的)。还解释了增加的内存使用量。
在未来版本的pandas中,我计划通过简单的顺序轴索引来改善这类代码在简单数据上的性能。我将在GitHub问题跟踪器上记录您的用例。