使用Pandas中的fillna()和lambda函数替换NaN值

3

我正尝试在 Pandas 中编写 fillna() 或 lambda 函数,检查 'user_score' 列是否为 NaN,如果是,则使用另一个 DataFrame 中的列数据。我尝试了两个选项:

games_data['user_score'].fillna(
    genre_score[games_data['genre']]['user_score']
    if np.isnan(games_data['user_score'])
    else games_data['user_score'],
    inplace = True
)

# but here is 'ValueError: The truth value of a Series is ambiguous'

并且

games_data['user_score'] = games_data.apply(
    lambda row: 
    genre_score[row['genre']]['user_score'] 
    if np.isnan(row['user_score'])
    else row['user_score'],
    axis=1
)

# but here is 'KeyError' with another column from games_data

我的数据框:

games_data

enter image description here

genre_score

enter image description here

我将非常感谢任何帮助!

3个回答

2
你也可以直接使用user_score_by_genre映射来调用fillna()函数:
user_score_by_genre = games_data.genre.map(genre_score.user_score)
games_data.user_score = games_data.user_score.fillna(user_score_by_genre)

顺便提一下,如果games_data.user_score永远不会偏离genre_score的值,你可以跳过fillna()直接将其赋值给games_data.user_score

games_data.user_score = games_data.genre.map(genre_score.user_score)

在 Pandas 中,内置的 Series.where 函数也可以使用,并且更加简洁:

df1.user_score.where(df1.user_score.isna(), df2.user_score, inplace=True)


1
谢谢您的回答,但这并不完全是我所需要的。请查看我在Mayank Porwal的回答中的评论。 - MaxB
@MaxB 仔细看了一下,我不清楚数据框的样子,特别是 genre_score。你能否提供一些来自 games_datagenre_score 的样本行? - tdy
1
刚刚完成了,你可以查看问题。我已经得到了一个解决方案,很快会发布。 - MaxB
1
@MaxB 看起来你已经有一个可行的解决方案了,但是只是为了参考,我添加了另一种选项,直接使用 fillna(user_score_by_genre) - tdy
@MaxB 没问题。顺便问一下,games_data.user_score 是否可以从 genre_score 值偏离呢?如果不行,你实际上可以跳过 fillna() 步骤,直接将映射赋值给 games_data.user_scoregames_data.user_score = games_data.genre.map(genre_score.user_score) - tdy
1
我认为这不是一个好主意,因为我会从genre_score中单独为每个流派填补games_data的空缺,并且这种方法会模糊数据。 - MaxB

1
使用 numpy.where
import numpy as np

df1['user_score'] = np.where(df1['user_score'].isna(), df2['user_score'], df1['user_score'])

谢谢,但这不是我需要的。df1和df2它们的大小不同,所以我必须从df2中通过键选择特定值来替换df1中的每个NaN值,就像我的示例中所示df2[df1['genre']]['user_score']。结果可能是这样的:df1['user_score'] = np.where(df1['user_score'].isna(), df2[df1['genre']]['user_score'], df1['user_score']) - MaxB

1
我发现解决方案的部分在这里
我使用series.map:
user_score_by_genre = games_data['genre'].map(genre_score['user_score'])

之后我使用了@MayankPorwal的答案:
games_data['user_score'] = np.where(games_data['user_score'].isna(), user_score_by_genre, games_data['user_score'])

我不确定这是最好的方法,但对我来说它有效。


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