假设我们可以选择数据的格式。什么是理想的?因为我们
想要收集每个TeamID 的统计信息,理想情况下我们会有一个TeamIDs 列
并为每个统计数据(包括结果)单独列。
所以数据看起来像这样:
| 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 的列。如果您有其他列,例如 Location 或
Officials 与 Day 一样,不属于 Losing 或 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])
是创建一个多级列索引(称为a
MultiIndex) 其中
标签列Losing 或Winning 视情况而定。
请注意,通过分离标签的Losing 或Winning 部分,
标签的其余部分将重复。
我们最终得到一个 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 和 reset_index 是 4 种基本的 DataFrame 重塑操作。
这 4 种方法一起使您可以将 DataFrame 中的数据移动到您想要的任何位置
want -- 在列、行索引或列索引中。
上面的代码是如何使用这些工具的示例(好吧,四个中的三个)
将reshape data 转换为所需的形式。