2017-08-25 112 views

回答

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 
+0

第一次注意'fillna'可以這樣,謝謝:))+ 1 – Wen

2

如果df1df2是你dataframes,您可以創建一個映射,然後調用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

老兄! 'dict(df2.values)'很漂亮。我會偷...借來的。 – piRSquared

+0

@piRSquared無論如何! –

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'}) 
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 
相關問題