使用Pandas / Python更新可变大小的数据框

我已经将一张excel表格导入了Pandas的一个数据框中。 空白值被“NA”取代。 我想要做的是,对于每个行值,将其replace为基于字典或数据框的索引。

df1 = pd.DataFrame( {'c1':['a','a','b','b'], 'c2':['1','2','1','3'], 'c3':['2','NA','3','NA']},index=['first','second','third','last']) >>> df1 c1 c2 c3 first a 1 2 second a 2 NA third b 1 3 last b 3 NA 

我想根据另一个dataframe(或字典)的指数replace每行中的值。

 df2=pd.DataFrame( {'val':['v1','v2','v3']},index=['1','2','3']) >>> df2 val 1 v1 2 v2 3 v3 

这样的输出成为

 >>> out c1 c2 c3 first a v1 v2 second a v2 NA third b v1 v3 last b v3 NA 

你如何通过pandas和/或Python来做到这一点? 一种方法是逐行search,但也许有一个更简单的方法?

编辑:重要的是,性能成为我真实情况下的问题,因为我正在处理一个'df1'的大小是4653行×1984列

先谢谢你

原始答案

 s = df1.squeeze() df2.replace(s) 

replace是非常非常缓慢的。 对于像您这样的大型数据集,请查看下面的例子,在20秒内完成了超过3000万个值(超过1000万个值)。 查找系列包含从0到100万的900k值。

“地图”要快得多。 map唯一的问题是,它会replace一个没有find的值,所以你将不得不使用fillna与原始的DataFrame来replace那些缺less的值。

 n = 10000000 df = pd.DataFrame({'c1':np.random.choice(list('abcdefghijkl'), n), 'c2':np.random.randint(0, 1000000, n), 'c3':np.random.randint(0, 1000000, n)}) s = pd.Series(index=np.random.choice(np.arange(1000000), 900000, replace=False), data=np.random.choice(list('adsfjhqwoeriouzxvmn'), 900000, replace=True)) df.stack().map(s).unstack().fillna(df) 

你也可以做到这一点,我的数据运行得更快,但是你的数据非常宽,所以速度可能会变慢

 df.apply(lambda x: x.map(s)).fillna(df) 

在一个类似于你的DataFrame上,我需要6秒才能完成。

 df = pd.DataFrame(np.random.randint(0, 1000000, (5000, 2000))) df.stack().map(s).unstack().fillna(df) 

一种方法是stack + replace + stack组合:

 df1.stack().replace(df2.val).unstack() 

在这里输入图像说明