熊猫数据框的条件过滤

新手上路,请多包涵

我有一个关于足球结果的熊猫数据框。数据框的每一行代表一场足球比赛。每场比赛信息如下:

 Day | WinningTeamID | LosingTeamID | WinningPoints | LosingPoints | WinningFouls | ... |
1          13             1              45                5               3
1          12             4              21                12              4

也就是说,信息是根据游戏结果来划分的:赢或输。我想检索特定团队(例如 12)的每场比赛的数据。

 Day | Points | Fouls | ... |
1       21       4     ...
2       32       6     ...

最简单的方法是扫描整个数据帧,检查特定的 teamID 是否在 WinningIDLosingID 上,然后基于此检索“ Losing-columns ”或“ Winning-columns ”。是否有更“优雅”的切片熊猫数据框的方式?这只会给我第 12 队参与的比赛子集。

 df[df[WinningTeamID == 12] | [LosingTeamID == 12]]

如何过滤这些数据并创建所需的数据框?

原文由 NCL 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 429
2 个回答

假设我们可以选择数据的格式。什么是理想的?因为我们想收集每个 TeamID 的统计数据,理想情况下我们会有一列 TeamID s 和每个统计数据的单独列,包括结果。

所以数据看起来像这样:

 | Day | Outcome | TeamID | Points | Fouls |
|   1 | Winning |     13 |     45 |     3 |
|   1 | Losing  |      1 |      5 |   NaN |
|   1 | Winning |     12 |     21 |     4 |
|   1 | Losing  |      4 |     12 |   NaN |

以下是我们如何将给定数据操作成所需的形式:

 import numpy as np
import pandas as pd

df = pd.DataFrame({'Day': [1, 1], 'LosingPoints': [5, 12], 'LosingTeamID': [1, 4], 'WinningFouls': [3, 4], 'WinningPoints': [45, 21], 'WinningTeamID': [13, 12]})
df = df.set_index(['Day'])
columns = df.columns.to_series().str.extract(r'^(Losing|Winning)?(.*)', expand=True)
columns = pd.MultiIndex.from_arrays([columns[col] for col in columns],
                                    names=['Outcome', None])
df.columns = columns
df = df.stack(level='Outcome').reset_index()
print(df)

产量

   Day  Outcome  Fouls  Points  TeamID
0    1   Losing    NaN       5       1
1    1  Winning    3.0      45      13
2    1   Losing    NaN      12       4
3    1  Winning    4.0      21      12

现在我们可以获得关于 TeamID 12 的所有统计信息使用

print(df.loc[df['TeamID']==12])
#    Day  Outcome  Fouls  Points  TeamID
# 3    1  Winning    4.0      21      12

df = df.set_index(['Day'])Day 列移动到索引中。

Day 放在索引中的目的是“保护”它免受操作(主要是 stack 调用),这些操作仅用于标记为 Losing Winning 3 的列 --- 。 If you had other columns, such as Location or Officials which, like Day , do not pertain to Losing or Winning ,然后您还想将它们包含在 set_index 调用中:例如 df = df.set_index(['Day', 'Location', 'Officials'])

尝试从上面的代码中注释掉 df = df.set_index(['Day']) 。然后逐行执行代码。特别是,比较 df.stack(level='Outcome') 有和没有 set_index 调用时的样子:

随着 df = df.set_index(['Day'])

 In [26]: df.stack(level='Outcome')
Out[26]:
             Fouls  Points  TeamID
Day Outcome
1   Losing     NaN       5       1
    Winning    3.0      45      13
    Losing     NaN      12       4
    Winning    4.0      21      12

没有 df = df.set_index(['Day'])

 In [29]: df.stack(level='Outcome')
Out[29]:
           Day  Fouls  Points  TeamID
  Outcome
0 NaN      1.0    3.0      45      13
  Losing   NaN    NaN       5       1
  Winning  1.0    3.0      45      13
1 NaN      1.0    4.0      21      12
  Losing   NaN    NaN      12       4
  Winning  1.0    4.0      21      12

如果没有 set_index 调用,您最终会得到不需要的行 Outcome 等于 NaN 的行。


的目的

columns = df.columns.to_series().str.extract(r'^(Losing|Winning)?(.*)', expand=True)
columns = pd.MultiIndex.from_arrays([columns[col] for col in columns],
                                    names=['Outcome', None])

是创建一个多级列索引(称为 MultiIndex ),它根据需要标记列 LosingWinning 。请注意,通过分离标签的 LosingWinning 部分,标签的其余部分将重复。

我们最终得到一个 DataFrame, df ,例如,有两列标记为“Points”。这允许 Pandas 将这些列识别为某种相似的列。

最大的收获——我们经历设置 MultiIndex 的麻烦的原因是这些“相似”的列可以通过调用 df.stack 来“统一”:

 In [47]: df
Out[47]:
Outcome Losing        Winning
        Points TeamID   Fouls Points TeamID
Day
1            5      1       3     45     13
1           12      4       4     21     12

In [48]: df.stack(level="Outcome")
Out[48]:
             Fouls  Points  TeamID
Day Outcome
1   Losing     NaN       5       1
    Winning    3.0      45      13
    Losing     NaN      12       4
    Winning    4.0      21      12

stack , unstack , set_index and reset_index are the 4 fundamental DataFrame reshaping operations.

  • df.stack 将列索引的一个(或多个)级别移动到行索引中。
  • df.unstack 将行索引的一个(或多个)级别移动到列索引中。
  • df.set_index 将列值移动到行索引中
  • df.reset_index 将行索引的一个(或多个)级别移动到值的列中

结合使用这 4 种方法,您可以将 DataFrame 中的数据移动到您想要的任何位置——在列、行索引或列索引中。

上面的代码是如何使用这些工具(嗯,四个中的三个)将 数据重塑 为所需形式的示例。

原文由 unutbu 发布,翻译遵循 CC BY-SA 3.0 许可协议

df.query['WinningTeamID == 12 | LosingTeamID == 12']

原文由 Ajay Ohri 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题