簡體   English   中英

通過從其他DataFrame中選擇值,在Pandas DataFrame中填充NaN

[英]Fill NaN in Pandas DataFrame by selecting value from other DataFrame

我正在玩泰坦尼克號數據集,並試圖填寫年齡值。 我的數據框看起來像:

 Dataframe df

    Survived  Pclass   Age  SibSp  Parch      Fare  male  Q  S   Title
0           0       3  22.0      1      0    7.2500     1  0  1      Mr
1           1       1  38.0      1      0   71.2833     0  0  0     Mrs
2           1       3  26.0      0      0    7.9250     0  0  1    Miss
3           1       1  35.0      1      0   53.1000     0  0  1     Mrs
4           0       3  35.0      0      0    8.0500     1  0  1      Mr
5           0       3   NaN      0      0    8.4583     1  1  0      Mr

DataFrame age_df
                    3        1        2
    Mr        28.7249  41.5805  32.7683
    Mrs       33.5152  40.8824  33.6829
    Miss      16.1232       30  22.3906
    Master    5.35083  5.30667  2.25889
    Don            40       40       40
    Rev       43.1667  43.1667  43.1667
    Dr             42    43.75     38.5
    Mme            24       24       24
    Ms             28       28       28
    Major        48.5     48.5     48.5
    Lady           48       48       48
    Sir            49       49       49
    Mlle           24       24       24
    Col            58       58       58
    Capt           70       70       70
    Countess       33       33       33
    Jonkheer       38       38       38

我想根據df['Title']df['Pclass'] age_df中的相應值填充df['Age']缺失值

我想出了這個,但沒有一個NaN被覆蓋。

for tit in df['Title'].unique():
    for cls in [1,2,3]:
        df.loc[ (df['Age'].isna() == True) &
                (df['Title'] == tit) &
                (df['Pclass'] == cls)]['Age'] = age_df.loc[tit][cls]

此外,我認為這不應該使用嵌套循環。 我該怎么做?

一種方法可以是使用applyifelse如下條件:

df['Age'] = df.apply(lambda row: age_df.loc[row.Title, row.Pclass] 
                                               if pd.isnull(row.Age) 
                                               else row.Age, axis=1)

您可以使用lookup

In [75]: s = pd.Series(age_df.lookup(df.Title, df.Pclass), index=df.index)    
In [76]: s
Out[76]: 
0    28.7249
1    40.8824
2    16.1232
3    40.8824
4    28.7249
5    28.7249
dtype: float64

In [77]: df.Age = df.Age.fillna(s)   
In [78]: df.Age
Out[78]: 
0    22.0000
1    38.0000
2    26.0000
3    35.0000
4    35.0000
5    28.7249
Name: Age, dtype: float64

使用loc[,]而不是loc[][]

for tit in df['Title'].unique():
    for cls in [1,2,3]:
        df.loc[ (df['Age'].isna() == True) &
                (df['Title'] == tit) &
                (df['Pclass'] == cls), 'Age'] = age_df.loc[tit,cls]

我仍然很好奇如何在沒有循環的情況下完成它。

您可以通過循環遍歷較小數量的Pclass來擺脫一個循環,然后使用標題來映射值。

for col in age_df:
    mask = (df.Age.isnull()) & (df.Pclass==int(col))
    df.loc[mask, 'Age'] = df.loc[mask, 'Title'].map(age_df[col])

   Survived  Pclass      Age  SibSp  Parch     Fare  male  Q  S Title
0         0       3  22.0000      1      0   7.2500     1  0  1    Mr
1         1       1  38.0000      1      0  71.2833     0  0  0   Mrs
2         1       3  26.0000      0      0   7.9250     0  0  1  Miss
3         1       1  35.0000      1      0  53.1000     0  0  1   Mrs
4         0       3  35.0000      0      0   8.0500     1  0  1    Mr
5         0       3  28.7249      0      0   8.4583     1  1  0    Mr

你可以使用melt來重塑你的age_df整齊的格式 , then合並and填充`。

age_df = age_df.melt('Title', var_name='Pclass')
age_df[:4]
    Title   Pclass  value
0   Mr      3       28.7249
1   Mrs     3       33.5152
2   Miss    3       16.1232

df = df.merge(age_df, how='left')
idx = df.Age.isnull()
df.Age[idx] = df.value[idx]

這不是最短的方法,但在閱讀了所有其他答案之后。 我仍然愛我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM