python - Pandas 数据帧矢量化/过滤:ValueError:只能比较标记相同的系列对象
问题描述
我有两个带有 NHL 曲棍球统计数据的数据框。一个包含过去十年中每支球队的每场比赛,另一个是我想用计算值填充它的地方。简而言之,我想从一支球队的前五场比赛中获取一个指标,将其相加,然后将其放入另一个 df 中。我在下面修剪了我的 dfs 以排除其他统计数据,并且只会查看一个统计数据。
df_all 包含所有游戏:
>>> df_all
season gameId playerTeam opposingTeam gameDate xGoalsFor xGoalsAgainst
1 2008 2008020001 NYR T.B 20081004 2.287 2.689
6 2008 2008020003 NYR T.B 20081005 1.793 0.916
11 2008 2008020010 NYR CHI 20081010 1.938 2.762
16 2008 2008020019 NYR PHI 20081011 3.030 3.020
21 2008 2008020034 NYR N.J 20081013 1.562 3.454
... ... ... ... ... ... ... ...
142576 2015 2015030185 L.A S.J 20160422 2.927 2.042
142581 2017 2017030171 L.A VGK 20180411 1.275 2.279
142586 2017 2017030172 L.A VGK 20180413 1.907 4.642
142591 2017 2017030173 L.A VGK 20180415 2.452 3.159
142596 2017 2017030174 L.A VGK 20180417 2.427 1.818
df_sum_all 将包含计算的统计信息,现在它有一堆空列:
>>> df_sum_all
season team xg5 xg10 xg15 xg20
0 2008 NYR 0 0 0 0
1 2009 NYR 0 0 0 0
2 2010 NYR 0 0 0 0
3 2011 NYR 0 0 0 0
4 2012 NYR 0 0 0 0
.. ... ... ... ... ... ...
327 2014 L.A 0 0 0 0
328 2015 L.A 0 0 0 0
329 2016 L.A 0 0 0 0
330 2017 L.A 0 0 0 0
331 2018 L.A 0 0 0 0
这是我计算 xGoalsFor 和 xGoalsAgainst 比率的函数。
def calcRatio(statfor, statagainst, games, season, team, statsdf):
tempFor = float(statsdf[(statsdf.playerTeam == team) & (statsdf.season == season)].nsmallest(games, 'gameDate').eval(statfor).sum())
tempAgainst = float(statsdf[(statsdf.playerTeam == team) & (statsdf.season == season)].nsmallest(games, 'gameDate').eval(statagainst).sum())
tempRatio = tempFor / tempAgainst
return tempRatio
我相信这足够合乎逻辑。我输入了我想计算比例的数据,要计算的比赛场次,要匹配的赛季和球队,然后从哪里获取数据。我已经分别测试了这些函数,并且知道我可以很好地过滤,并对统计数据求和,等等。这是 tempFor 计算的独立实现的示例:
>>> statsdf = df_all
>>> team = 'TOR'
>>> season = 2015
>>> games = 3
>>> tempFor = float(statsdf[(statsdf.playerTeam == team) & (statsdf.season == season)].nsmallest(games, 'gameDate').eval(statfor).sum())
>>> print(tempFor)
8.618
看?它返回一个值。但是我不能在整个数据框中做同样的事情。我错过了什么?我认为这种工作方式基本上适用于每一行,它将“xg5”列设置为 calcRatio 函数的输出,该函数使用该行的“季节”和“团队”来过滤 df_all。
>>> df_sum_all['xg5'] = calcRatio('xGoalsFor','xGoalsAgainst',5,df_sum_all['season'], df_sum_all['team'], df_all)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in calcRatio
File "/home/sebastian/.local/lib/python3.6/site-packages/pandas/core/ops/__init__.py", line 1142, in wrapper
raise ValueError("Can only compare identically-labeled " "Series objects")
ValueError: Can only compare identically-labeled Series objects
干杯,感谢您的帮助!
更新:我使用了 iterrows() 并且效果很好,所以我一定不能很好地理解矢量化。但是,它是相同的功能 - 为什么它以一种方式工作,而不是另一种方式?
>>> emptyseries = []
>>> for index, row in df_sum_all.iterrows():
... emptyseries.append(calcRatio('xGoalsFor','xGoalsAgainst',5,row['season'],row['team'], df_all))
...
>>> df_sum_all['xg5'] = emptyseries
__main__:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
>>> df_sum_all
season team xg5 xg10 xg15 xg20
0 2008 NYR 0.826260 0 0 0
1 2009 NYR 1.288390 0 0 0
2 2010 NYR 0.915942 0 0 0
3 2011 NYR 0.730498 0 0 0
4 2012 NYR 0.980744 0 0 0
.. ... ... ... ... ... ...
327 2014 L.A 0.823998 0 0 0
328 2015 L.A 1.147412 0 0 0
329 2016 L.A 1.054947 0 0 0
330 2017 L.A 1.369005 0 0 0
331 2018 L.A 0.721411 0 0 0
[332 rows x 6 columns]
解决方案
“ValueError:只能比较标签相同的系列对象”
tempFor = float(statsdf[(statsdf.playerTeam == team) & (statsdf.season == season)].nsmallest(games, 'gameDate').eval(statfor).sum())
tempAgainst = float(statsdf[(statsdf.playerTeam == team) & (statsdf.season == season)].nsmallest(games, 'gameDate').eval(statagainst).sum())
变量的输入:
team: df_sum_all['team']
season: df_sum_all['season']
statsdf: df_all
因此,在代码(statsdf.playerTeam == team)中,它将比较来自df_sum_all和来自df_all的系列。如果这两个标签不同,您将看到上述错误。
推荐阅读
- c# - ToString 参数错误
- html - 从 div 中剪切/遮罩三角形(旗帜形状)
- powershell - ErrorAction 在 PowerShell 脚本中默认停止
- c# - 为什么在完成“if”条件后我的“else”条件会激活(C#)
- tcl - 放置与变量匹配的线条和着色词
- ruby-on-rails-5 - 嗨,我想在 Rails 中创建两个(或更多)博客,在它们之间共享类似 WordPress 广播插件的文章
- javascript - 已解决:IE 11 中的会话存储
- django-rest-framework - 如何将部分数据保存在单独的模型中,然后查询该数据是否存在?
- r - 如何一次删除多个data.frames中的行和填充列?
- c - 如何使用代码中已定义的变量为变量设置值?