pandas数据框的条件过滤

时间:2017-06-17 18:25:46

标签: python pandas filter slice

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

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是否在 WinningID LosingID 上,然后根据它检索“丢失列“或” Winning-columns “。 是否有一种更“优雅”的切片熊猫数据帧的方式? 这将简单地为我提供团队12参与的匹配子集。

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

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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放在索引中的目的是“保护”它免受操纵 (主要是stack调用)仅适用于标记为LosingWinning的列。如果您有其他列,例如LocationOfficials Day,与LosingWinning无关, 您也希望将它们包含在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

stackunstackset_indexreset_index是4个基本的DataFrame重塑操作。

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

这四种方法共同允许您在DataFrame中的任何位置移动数据 想要 - 在列中,行索引或列索引。

以上代码是如何使用这些工具的示例(嗯,四个中的三个) 到reshape data到所需的形式。

答案 2 :(得分:0)

我认为应该更像是:

df.query('columnX == 15 | columnY == 25')