根据另一个数据框中的列填充数据框中的空值

时间:2017-08-25 14:32:09

标签: python pandas dataframe replace

我有一个像这样的数据框df1

enter image description here

我想根据不同的名称在nan0填充另一个数据框score中的多个值。

enter image description here

我怎么能这样做?

4 个答案:

答案 0 :(得分:3)

选项1
简短版

df1.score = df1.score.mask(df1.score.eq(0)).fillna(
    df1.name.map(df2.set_index('name').score)
)
df1

  name  score
0    A   10.0
1    B   32.0
2    A   10.0
3    C   30.0
4    B   20.0
5    A   45.0
6    A   10.0
7    A   10.0

选项2
使用searchsorted的有趣版本。 df2必须按'name'排序。

i = np.where(np.isnan(df1.score.mask(df1.score.values == 0).values))[0]
j = df2.name.values.searchsorted(df1.name.values[i])
df1.score.values[i] = df2.score.values[j]
df1

  name  score
0    A   10.0
1    B   32.0
2    A   10.0
3    C   30.0
4    B   20.0
5    A   45.0
6    A   10.0
7    A   10.0

答案 1 :(得分:2)

如果df1df2是您的数据框,则可以创建映射,然后调用pd.Series.replace

df1 = pd.DataFrame({'name' : ['A', 'B', 'A', 'C', 'B', 'A', 'A', 'A'], 
                     'score': [0, 32, 0, np.nan, np.nan, 45, np.nan, np.nan]})
df2 = pd.DataFrame({'name' : ['A', 'B', 'C'], 'score' : [10, 20, 30]})

print(df1)

  name  score
0    A    0.0
1    B   32.0
2    A    0.0
3    C    NaN
4    B    NaN
5    A   45.0
6    A    NaN
7    A    NaN

print(df2) 

  name  score
0    A     10
1    B     20
2    C     30

mapping = dict(df2.values)

df1.loc[(df1.score.isnull()) | (df1.score == 0), 'score'] =\
               df1[(df1.score.isnull()) | (df1.score == 0)].name.replace(mapping)

print(df1)

  name  score
0    A   10.0
1    B   32.0
2    A   10.0
3    C   30.0
4    B   20.0
5    A   45.0
6    A   10.0
7    A   10.0

答案 2 :(得分:1)

或使用mergefillna

import pandas as pd
import numpy as np

df1.loc[df.score==0,'score']=np.nan
df1.merge(df2,on='name',how='left').fillna(method='bfill',axis=1)[['name','score_x']]\
    .rename(columns={'score_x':'score'})

答案 3 :(得分:1)

此方法更改顺序(结果将按name排序)。

df1.set_index('name').replace(0, np.nan).combine_first(df2.set_index('name')).reset_index()

  name  score
0    A     10
1    A     10
2    A     45
3    A     10
4    A     10
5    B     32
6    B     20
7    C     30