2

我想知道为什么pandas在重新索引系列时会占用大量内存。

我创建了一个简单的数据集:

a = pd.Series(np.arange(5e7, dtype=np.double))

根据top我的 Ubuntu,整个会话大约 820MB。

现在,如果我将其切片以提取前 100 个元素:

a_sliced = a[:100]

这表明没有增加内存消耗。

相反,如果我a在同一范围内重新索引:

a_reindexed = a.reindex(np.arange(100))

我的内存消耗约为 1.8GB。也尝试清理gc.collect但没有成功。

我想知道这是否是预期的,以及是否有一种解决方法可以在没有大量内存开销的情况下重新索引大型数据集。

我正在使用pandas来自 github 的最新快照。

4

2 回答 2

2

copy=False设置FYI 时要非常小心。这可能会导致一些奇怪的效果。如果您的数据相对于索引大小(看起来确实如此)很大,则复制索引是“便宜的”。

如果要消除重新索引后关联的内存,请执行以下操作:

s = a_big_series
s2 = s.reindex(....)

仍然使用内存,因为底层数据只是旧数据的视图(取决于你如何切片它。它可以是副本,但这取决于 numpy)。

s2 = s.reindex(....).copy()
del s

这将释放内存

于 2013-08-06T12:26:54.120 回答
2

Index 使用 Hashtable 将标签映射到位置。您可以通过Series.index._engine.mapping. 必要时会创建此映射。如果是索引is_monotonic,可以使用asof()

import numpy as np
import pandas as pd
idx =["%07d" % x for x in range(int(2e6))]
a = pd.Series(np.arange(2e6, dtype=np.double), index=idx)
new_index = ["0000003", "0000020", "000002a"]

print a.index._engine.mapping # None
print a.reindex(new_index)
print a.index._engine.mapping # <pandas.hashtable.PyObjectHashTable object at ...>

a = pd.Series(np.arange(2e6, dtype=np.double), index=idx)
print a.asof(new_index)
print a.index._engine.mapping # None

如果您想要更多地控制不存在的标签,您可以searchsorted()自己使用并执行逻辑:

>>> a.index[a.index.searchsorted(new_index)] 
Index([u'0000003', u'0000020', u'0000030'], dtype=object)
于 2013-08-06T07:27:38.150 回答