get_dummies python内存错误

时间:2015-07-09 15:27:49

标签: python pandas

我遇到的问题是数据集有400,000行和300个变量。我必须为具有3,000多个不同项目的分类变量获取虚拟变量。最后,我想得到一个包含3,300个变量或特征的数据集,以便我可以训练一个RandomForest模型。

以下是我尝试过的事情:

 df = pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1)

当我这样做时,我总会得到一个内存错误。我可以拥有的变量数量是否有限制?

如果我只使用前1000行(有374个不同类别),那就可以了。

有没有人能解决我的问题?我正在使用的计算机有8 GB的内存。

1 个答案:

答案 0 :(得分:23)

更新:从版本0.19.0开始,get_dummies返回一个8位整数而不是64位浮点数,这将在许多情况下解决此问题,并使下面的as_type解决方案变得不必要。请参阅:get_dummies -- pandas 0.19.0

但在其他情况下,下面提到的sparse选项可能仍然有用。

原始答案:以下是尝试的几种可能性。两者都会大幅减少数据帧的内存占用,但您以后仍可能遇到内存问题。很难预测,你只需要尝试。

(请注意,我正在简化下面info()的输出)

df = pd.DataFrame({ 'itemID': np.random.randint(1,4,100) })

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1).info()

itemID       100 non-null int32
itemID__1    100 non-null float64
itemID__2    100 non-null float64
itemID__3    100 non-null float64

memory usage: 3.5 KB

这是我们的基线。每个虚拟列占用800个字节,因为样本数据有100行,get_dummies似乎默认为float64(8个字节)。这似乎是一种不必要的低效方式来存储虚拟对象,因为你可以尽可能少地使用它,但可能有一些我不知道的原因。

所以,首先尝试,只需更改为一个字节的整数(这似乎不是get_dummies的选项,因此必须使用astype(np.int8)进行转换。

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_').astype(np.int8)], 
                              axis=1).info()

itemID       100 non-null int32
itemID__1    100 non-null int8
itemID__2    100 non-null int8
itemID__3    100 non-null int8

memory usage: 1.5 KB

每个虚拟列现在占用内存的1/8。

或者,您可以使用sparse的{​​{1}}选项。

get_dummies

相当可观的节省。 pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_',sparse=True)], axis=1).info() itemID 100 non-null int32 itemID__1 100 non-null float64 itemID__2 100 non-null float64 itemID__3 100 non-null float64 memory usage: 2.0 KB 输出在某种程度上隐藏了节省的方式,但您可以查看内存使用量的值,以了解总节省量。

其中哪些在实践中效果更好取决于您的数据,所以您只需要尝试一下(或者甚至可以将它们组合起来)。