2017-06-17 181 views
1

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

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,然后此基础上,检索“流失柱”或“ Winning-columns“。 有没有更“优雅”的方式来切割熊猫数据框? 这只会给我参与团队12的比赛的子集。

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

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

回答

0

假设我们可以选择数据的格式。什么是理想的?由于我们 想要根据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在索引的目的是“保护”它从仅用于标记LosingWinning列操作 (主要是stack呼叫)。如果你有其他列,如LocationOfficials其中,像Day,不属于LosingWinning,然后 你想要将它们包括在​​调用过:例如df = df.set_index(['Day', 'Location', 'Officials'])

尝试从上面的代码注释df = df.set_index(['Day'])。然后逐行执行代码。 尤其是比较有什么df.stack(level='Outcome')看起来像有和没有​​电话:

随着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 

没有​​叫你最终行时,你不想要 - 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”。 这允许熊猫识别这些列在某种程度上类似。

带来的最大益处 - 为什么我们通过建立多指标的的麻烦去的原因是,这些“相似”列可以是“统一”通过调用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 

stackunstack,​​和reset_index是4种基本的DataFrame整形操作。

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

在一起的一列,这4种方法让你在你的数据帧数据移动任何你想要的地方 - 在列中,行索引或列索引。

上述代码是如何将这些工具(以及四个中的三个) 至reshape data转换为所需形式的示例。

+0

谢谢!这绝对是工作!我对熊猫相当陌生,请你向我解释为什么你在'Day'上使用set_index?以下行的目标是什么?我所理解的唯一部分是您提取包含丢失或获胜的列。 – NCL

+0

非常感谢您的好评和解答! – NCL

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

尽管此代码可能会回答问题,但提供关于此代码为何和/或如何回答问题的其他上下文可提高其长期价值。 –

+0

熊猫数据框中的.query选项使得传递SQL查询更容易,比如选择数据 –