python - pandas.unique() 奇怪的内存消耗
问题描述
在分析我的算法的内存消耗时,我很惊讶有时对于较小的输入需要更多的内存。
这一切都归结为以下用法pandas.unique()
:
import numpy as np
import pandas as pd
import sys
N=int(sys.argv[1])
a=np.arange(N, dtype=np.int64)
b=pd.unique(a)
N=6*10^7
它需要3.7GB
峰值内存,但需要N=8*10^7
"only" 3GB
。
扫描不同的输入大小会产生下图:
出于好奇和自我教育:如何解释 , 周围的违反直觉的行为(即更多的内存用于更小的输入大小) ?N=5*10^7
N=1.3*10^7
以下是在 Linux 上生成内存消耗图的脚本:
pandas_unique_test.py:
import numpy as np
import pandas as pd
import sys
N=int(sys.argv[1])
a=np.arange(N, dtype=np.int64)
b=pd.unique(a)
show_memory.py:
import sys
import matplotlib.pyplot as plt
ns=[]
mems=[]
for line in sys.stdin.readlines():
n,mem = map(int, line.strip().split(" "))
ns.append(n)
mems.append(mem)
plt.plot(ns, mems, label='peak-memory')
plt.xlabel('n')
plt.ylabel('peak memory in KB')
ymin, ymax = plt.ylim()
plt.ylim(0,ymax)
plt.legend()
plt.show()
run_perf_test.sh:
WRAPPER="/usr/bin/time -f%M" #peak memory in Kb
N=1000000
while [ $N -lt 100000000 ]
do
printf "$N "
$WRAPPER python pandas_unique_test.py $N
N=`expr $N + 1000000`
done
现在:
sh run_perf_tests.sh 2>&1 | python show_memory.py
解决方案
让我们来看看...
pandas.unique
说它是“基于哈希表的唯一”。
它调用此函数来为您的数据获取正确的哈希表实现,即htable.Int64HashTable
.
哈希表初始化为size_hint
= 值向量的长度。这意味着kh_resize_DTYPE(table, size_hint)
被调用。
这些函数在khash.h
.
它似乎为(size_hint >> 5) * 4 + (size_hint) * 8 * 2
存储桶分配了字节的内存(可能更多,也可能更少,我可能会离开这里)。
然后,HashTable.unique()
被调用。
它分配一个 empty ,从128Int64Vector
开始,每当它们被填充时,它们的大小似乎会增加四倍。
然后它会遍历你的值,确定它们是否在哈希表中;如果没有,它们将被添加到哈希表和向量中。(这是向量可能增长的地方;由于大小提示,哈希表不需要增长。)
最后,使 NumPyndarray
指向向量。
所以,呃,我认为你看到向量大小在某些阈值处翻了两番(如果我的深夜数学站得住,那应该是,
>>> [2 ** (2 * i - 1) for i in range(4, 20)]
[
128,
512,
2048,
8192,
32768,
131072,
524288,
2097152,
8388608,
33554432,
134217728,
536870912,
2147483648,
8589934592,
34359738368,
137438953472,
...,
]
希望这对事情有所启发:)
推荐阅读
- javascript - 表小计和总计不计算
- angular - 如何获取此图像并使用http以角度4显示它?
- amazon-web-services - Terraform 了解哪些 AWS 资源
- c# - 如何将 SSL 证书更新发送到正在运行的应用程序?
- ef-code-first - 无法使用实体框架代码优先方法生成数据库表
- java - 如何从两个 hashMap 中检索公共键并将结果放入 ArrayList
- python - 带有 Plotly Dash 的日期滑块不起作用
- html - 在带有粘性列的表格上保留交替的行阴影
- swift - 渐变背景后 UI 消失
- ios - 在整个应用程序上设置日历类型