2017-06-17 120 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查詢更容易,比如選擇數據 –