假设我们可以选择数据格式。什么样的格式最理想?由于我们想要按
TeamID
收集统计信息,因此理想情况下,我们将拥有一个
TeamID
列和每个统计数据的单独列,包括结果。
因此,数据应该如下所示:
| 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])
df = df.set_index(['Day'])
将 Day
列移动到索引中。
将 Day
放入索引的目的是为了“保护”它免受旨在仅针对标记为Losing
或Winning
的列(主要是stack
调用)的操纵。如果您有其他列,例如像 Day
一样与Losing
或Winning
无关的Location
或Officials
等,则也需要在 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
Without 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),将“输掉”的或“赢得”的标签分别标记为
Losing
或
Winning
。通过将标签的“输掉”或“赢得”部分分离出来,可以使标签的剩余部分重复。最终获得一个名为
df
的DataFrame,例如有两列标签为“Points”,这使得Pandas能够将这些列识别为相似的列。
通过设置多级索引,我们可以通过调用
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
和 reset_index
是四个基本的 DataFrame 重塑操作。
这四种方法可以让您将数据从 DataFrame 中的任何位置移动到所需的位置,包括列、行索引或列索引。
上面的代码是如何使用这些工具(实际上是其中三个)来重塑数据为所需形式的示例。