假设我们可以选择数据的格式。什么是理想的?由于我们 想要根据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
在索引的目的是“保护”它从仅用于标记Losing
或Winning
列操作 (主要是stack
呼叫)。如果你有其他列,如Location
或 Officials
其中,像Day
,不属于Losing
或Winning
,然后 你想要将它们包括在调用过:例如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),其 标签列Losing
或Winning
适当。 请注意,通过将Losing
或Winning
部分标签分开, 标签的其余部分会变得重复。
我们最终得到了一个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
stack
,unstack
,和reset_index
是4种基本的DataFrame整形操作。
在一起的一列,这4种方法让你在你的数据帧数据移动任何你想要的地方 - 在列中,行索引或列索引。
上述代码是如何将这些工具(以及四个中的三个) 至reshape data转换为所需形式的示例。
谢谢!这绝对是工作!我对熊猫相当陌生,请你向我解释为什么你在'Day'上使用set_index?以下行的目标是什么?我所理解的唯一部分是您提取包含丢失或获胜的列。 – NCL
非常感谢您的好评和解答! – NCL