删除熊猫中的列的内存高效方法



在panda中删除列而不耗尽内存的最佳方法是什么?

我有一个很大的数据集,经过一些变量操作后,我需要删除大约一半的变量。我试着使用df.drop(vars, axis=1, inplace=True),但发现我的内存使用量激增了不少。没有inplacepatameter也是如此。

这正是这个老熊猫话题中讨论的话题,但它被关闭了,没有给出答案。SO上有很多类似的问题,但我还没有找到答案,特别是当从大数据帧中删除许多变量时,如何避免内存大幅增加。谢谢

正如@Kraigolas提到的问题中所建议的那样,由于各种原因,不建议就地使用,在这种情况下,它甚至不会带来好处。

通常,如果数据帧没有以尽可能优化的形式进行预处理,则丢弃操作在内存使用方面可能是繁重的。

铸造数据类型

例如,为了节省空间,您可以决定将所有列强制转换为精确的数据类型(请参阅pandas.DataFrame.dtypes和pandas.Data Frame.astype(

使用python 3.9、pandas 1.4.3和numpy 1.23.1以及tracemalloc:的示例

import pandas as pd
import numpy as np
import tracemalloc
df = pd.DataFrame(data=np.ones((10000,10000)))
tracemalloc.start()
df.drop(df.columns[0:1000], axis=1)
print(f"MB peak of RAM: {tracemalloc.get_traced_memory()[1] / 1024 / 1024}")
tracemalloc.stop()

输出将为687.13 MB

现在,如果将dtypes强制转换为int而不是默认的float64(明显地将tracemalloc的开始移动到预处理步骤之后,否则峰值会受到强制转换的影响(,如下所示:

df = pd.DataFrame(data=np.ones((10000,10000)))
df = df.astype('int8')
tracemalloc.start()
df.drop(df.columns[0:1000], axis=1)
print(f"MB peak of RAM: {tracemalloc.get_traced_memory()[1] / 1024 / 1024}")
tracemalloc.stop()

输出将86.31MB

使用"iloc"(如果可能(

如果可以通过索引列表来定位列(例如,根据某些标准用pandas.DataFrame.sort_values对它们进行重新排序(,则pandas的操作。DataFrame.iloc将大大提高效率和速度。

与之前的示例相比,使用带int8:的dtype铸造

tracemalloc.start()
df.iloc[:, 1000:]
print(f"MB peak of RAM: {tracemalloc.get_traced_memory()[1] / 1024 / 1024}")
tracemalloc.stop()

它只使用0.023 MB的RAM


通常,向量运算总是比使用简单但内部过程耗时的函数更具性能(甚至只有几个数量级(,尤其是在Panda中。

最新更新