提高Pandas数据框填充性能

3
我希望使用pandas来填充一个大的数据矩阵(90*90000),以及稍后会更大的一个(150000*800000)。目前我正在我的笔记本电脑上(8GB RAM,Haswell Core i5 2.2 GHz)测试较小的那个数据集,而更大的数据集将在服务器上运行。
这些列中有一些缺失值,我想用所有行中最常见的值来填充它们。
我的可行代码如下:
freq_val =  pd.Series(mode(df.ix[:,6:])[0][0], df.ix[:,6:].columns.values) #most frequent value per column, starting from the first SNP column (second row of 'mode'gives actual frequencies)
df_imputed = df.ix[:,6:].fillna(freq_val) #impute unknown SNP values with most frequent value of respective columns

在我的机器上,这个操作大约需要20分钟的时间。有没有其他的实现方法可以提高性能?


你可以测试隔离包含 NaN 的行的索引,然后使用 .loc() 手动将单元格设置为模式。我不知道它是否会给你更好的性能,但这是一个可供测试的替代方法。 - Alex Petralia
@AlexPetralia 感谢你的建议,我尝试了这种方法,但是掩盖 NaN 值并没有带来什么显著的改进。 - Dahlai
2个回答

2

尝试这个:

df_imputed = df.iloc[:, 6:].fillna(df.iloc[:, 6:].apply(lambda x: x.mode()).iloc[0])

谢谢你的建议。我尝试了这个实现,但它比我找到的解决方案慢了约40%。请参见下面的答案。 - Dahlai

2

我尝试了不同的方法。关键的学习是mode函数非常慢。相反,我使用np.unique (return_counts=True)和np.bincount实现了相同的功能。后者据说更快,但不能处理NaN值。

优化后的代码现在运行需要约28秒。MaxU的答案在我的机器上需要约48秒才能完成。

代码如下:

iter = range(np.shape(df.ix[:,6:])[1])
freq_val = np.zeros(np.shape(df.ix[:,6:])[1])
for i in iter:
    _, count = np.unique(df.ix[:,i+6], return_counts=True)
    freq_val[i] = count.argmax()
freq_val_series =  pd.Series(freq_val, df.ix[:,6:].columns.values) 
df_imputed = df.ix[:,6:].fillna(freq_val_series) 

感谢您的反馈!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接