在Pandas / Python中使用可变大小的行更新数据帧

时间:2017-01-19 13:08:03

标签: python excel pandas

我已将excel表格导入Pandas的数据框中。空白值被'NA'取代。我想要做的是,对于每个行值,根据字典或数据帧的索引替换它们。

ise myfile.ps1

我希望根据另一个数据帧(或字典)的索引替换每行中的值。

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

输出变为

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

>>> df2
   val
1  v1  
2  v2 
3  v3 

你会如何通过熊猫和/或Python来做到这一点?一种方法是逐行搜索,但也许有一种更简单的方法?

编辑:重要的是,性能在我的实际案例中成为一个问题,因为我正在处理一个'df1',其大小为4653行×1984列

提前谢谢

2 个答案:

答案 0 :(得分:4)

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

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

enter image description here

答案 1 :(得分:1)

原始答案

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

replace非常非常慢。对于更大的数据集,您可以检查以下示例,该示例在大约20秒内完成超过3000万个值(超过1000万个值)。查找系列包含从0到100万的900k值。

'map'要快得多。 map的唯一问题是它会替换未找到的值,因此您必须使用fillna与原始DataFrame替换这些缺失值。

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)