如何利用pandas fillna快速填充大量数据?

5
我有两个数据框,一个很大且有很多缺失值,另一个用于填充第一个数据框中的缺失数据。
数据框示例:
In[34]:
import pandas as pd
import numpy as np

df2 = pd.DataFrame({'A': [1, 1, 1, 2, 2, 2], 'B': [1, 0, 1, 1, 0, 0]})

df = pd.DataFrame({'A': [0, 1, 2, 3, 4, 5], 'B1': [1, np.nan, np.nan, 8, 9, 1],'B2':[1, np.nan, np.nan, 7, 6, 1], 'B3':[1, np.nan, np.nan, 8, 7, 1] })
df=df.set_index(['A'])
df2=df2.set_index(['A'])

In[35]:
df

Out[35]: 
   B1  B2  B3
A            
0   1   1   1
1 NaN NaN NaN
2 NaN NaN NaN
3   8   7   8
4   9   6   7
5   1   1   1

In[36]:
df2

Out[36]: 
   B
A   
1  1
1  0
1  1
2  1
2  0
2  0

我想做的是使用来自df2的数据填充df,同时考虑到当在df2中遇到第二个实例时B1不等于B2。 请参见下面的期望输出:
In[38]:
df

Out[38]: 
   B1  B2  B3
A            
0   1   1   1
1   1   0   1
2   1   0   0
3   8   7   8
4   9   6   7
5   1   1   1

B1、B2和B3中的NaN值已经被来自df2的数据填充。对于索引1和2,分别为1 0 1和1 0 0。 以下是我低效的for循环实现:
In[37]:
count=1
seen=[]

for t in range(0, len(df2)):
     if df2.index[t] not in seen:
         count=1
         seen.append(df2.index[t])
     else:
         count=count+1
     tofill=pd.DataFrame(df2.iloc[t]).transpose()
     tofill_dict={"B"+str(count):tofill.B}
     df=df.fillna(value=tofill_dict)

这种方法是可行的,但当数据集变大时,它可能需要较长时间。因此,我的问题是是否有更快的方法来实现这一点? 我听说过矢量化可能起作用,你会如何实现它?还有其他更快的方法吗?
1个回答

1

首先,您不能重置df2的索引。

您可以尝试使用 groupby - 每个组都会使用T来进行转置,然后通过df2的值fillna df

import pandas as pd
import numpy as np

df2 = pd.DataFrame({'A': [1, 1, 1, 2, 2, 2], 'B': [1, 0, 1, 1, 0, 0]})

df = pd.DataFrame({'A': [0, 1, 2, 3, 4, 5], 'B1': [1, np.nan, np.nan, 8, 9, 1],'B2':[1, np.nan, np.nan, 7, 6, 1], 'B3':[1, np.nan, np.nan, 8, 7, 1] })
df=df.set_index(['A'])
df2=df2.set_index(['A'])

print df
   B1  B2  B3
A            
0   1   1   1
1 NaN NaN NaN
2 NaN NaN NaN
3   8   7   8
4   9   6   7
5   1   1   1
print df2
   A  B
0  1  1
1  1  0
2  1  1
3  2  1
4  2  0
5  2  0

df2 = df2.groupby(df2.index).apply(lambda x: x.B.reset_index(drop=True).T)
df2.columns = df.columns
print df2
   B1  B2  B3
A            
1   1   0   1
2   1   0   0    

df = df.fillna(df2)
print df

    B1  B2  B3
A            
0   1   1   1
1   1   0   1
2   1   0   0
3   8   7   8
4   9   6   7
5   1   1   1

也许如果 df = df.fillna(df2) 不起作用,可以使用 df = df.combine_first(df2)。这取决于索引。

它是如何工作的?我无法将其与您的解决方案进行比较,因为出现错误:'NameError:全局名称'toappend'未定义'。 - jezrael
感谢您的回答jezrael!我已经修复了错误的原因,是我的问题,非常抱歉。我已经快速检查过了,当使用df2 = df2.groupby(df2.index).apply(lambda x: x.B.reset_index(drop=True).T)而不是df2 = df2.groupby('A').apply(lambda x: x.B.reset_index(drop=True).T)时,它可以工作。回家后需要在大型数据集上进行测试。 - HBX
好的,你是对的,但我认为你只是为了这个填充而重置了索引。所以我想要删除这个操作。我编辑了答案。 - jezrael

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