我想了解熊猫群岛,但我现在看到一些我不明白的行为。基本上,我有一个看起来像的数据集(只显示头部):
userId movieId rating timestamp parsed_time
0 1 2 3.5 1112486027 2005-04-02 23:53:47
1 1 29 3.5 1112484676 2005-04-02 23:31:16
2 1 32 3.5 1112484819 2005-04-02 23:33:39
3 1 47 3.5 1112484727 2005-04-02 23:32:07
4 1 50 3.5 1112484580 2005-04-02 23:29:40
我已经检查了数据集的NaN / null值,但没有。现在,我想计算每部电影的平均评分,以及标准偏差。
获得平均评分很简单:
ratings = pd.read_csv('ratings.csv', sep=',')
average_rating = ratings[['movieId','rating']].groupby('movieId',as_index=False).mean()
average_ratings.rename(columns={'rating':'AverageRating'}, inplace=True)
这给了我类似的东西:
movieId AverageRating
0 1 3.921240
1 2 3.211977
2 3 3.151040
3 4 2.861393
4 5 3.064592
所以这一切都很好,以及我对groupby()
和mean()
组合的期望。
现在,我想做同样的事情来计算电影评级的标准偏差,并将其作为新列添加到average_rating
df:
average_rating['StdDev'] = ratings[['movieId','rating']].groupby('movieId').std()
给了我:
movieId AverageRating StdDev
0 1 3.921240 NaN
1 2 3.211977 0.889012
2 3 3.151040 0.951150
3 4 2.861393 1.006642
4 5 3.064592 1.095702
这里让我感到困惑的是,NaN在我的StdDev专栏中首次出现。如果我手动提取行,比如movieId [1,2]并计算平均值和标准偏差,那就是:
print('Mean movieID 1:')
print(ratings[ratings['movieId']==1]['rating'].mean())
print('StdDev movieID 1:')
print(ratings[ratings['movieId']==1]['rating'].std())
print('Mean movieID:')
print(ratings[ratings['movieId']==2]['rating'].mean())
print('StdDev movieID 2:')
print(ratings[ratings['movieId']==2]['rating'].std())
我回来了:
Mean movieID 1:
3.921240
StdDev movieID 1:
0.889012
Mean movieID 2:
3.211977
StdDev movieID 2:
0.951150
所以对我来说,看起来groupby.std()
由于某种原因跳过第一个索引,用NaN替换它,然后填入正确的值,但移动了一个索引。我不明白这种行为,这不是我所期望的。任何人都可以在第二次使用groupby时向我解释这种行为,以及如何避免它/让它做我想做的事情?
答案 0 :(得分:2)
问题不是在计算标准差时发生,而是在将结果分配给新列StdDev
时发生。这是因为pandas隐式地通过索引进行分配。
以下代码应该有效,因为groupby
操作的结果都在movieId
上编入索引:
# note how I remove as_index=False
average_rating = ratings[['movieId','rating']].groupby('movieId').mean()
average_rating['StdDev'] = ratings[['movieId','rating']].groupby('movieId').std()
当然,你应该一气呵成:
ratings[['movieId','rating']].groupby('movieId').agg(['mean', 'std'])
更优雅(或至少更标准):
ratings.groupby('movieId')['rating'].agg(['mean', 'std'])
答案 1 :(得分:2)
这里的关键是,在你的第一个groupby中,你包括as_index=False
,所以创建的df有一个新的串行索引。在您的secong groupby中,您不包含as_index
参数,因此它使用MovieID作为索引。
当您在average_ratings
中将其指定为列时,索引不是指同一个事物。
在这种情况下恰好发生看起来您的索引已被移位,因为您有MovieID 1-5,整数索引0-4。 StdDev列中的空值仅反映了没有ID = 0的电影的事实。