pandas DataFrame 中的级别是什么?
What are levels in a pandas DataFrame?
我一直在阅读文档,许多解释和示例都使用 levels
作为理所当然的东西。恕我直言,文档缺乏对数据结构和定义的基本解释。
数据框中的级别是什么? MultiIndex
索引中的级别是什么?
通常一个 DataFrame 有一个一维索引和列:
x y
0 4 1
1 3 9
此处索引为 [0, 1],列为 ['x', 'y']。但是您可以在索引或列中有多个级别:
x y
a b c
0 7 4 1 3
8 3 9 5
此处列的第一级是 ['x'、'y'、'y'],第二级是 ['a'、'b'、'c']。索引的第一层是[0, 0],第二层是[7, 8].
我在分析 的答案时偶然发现了这个问题,但我觉得 John 的答案不够令人满意。经过几次实验后,我认为我理解了这些级别并决定分享:
简答:
级别是索引或列的一部分。
长答案:
我认为这个多列 DataFrame.groupby
示例很好地说明了索引级别。
假设我们有时间登录问题报告数据:
report = pd.DataFrame([
[1, 10, 'John'],
[1, 20, 'John'],
[1, 30, 'Tom'],
[1, 10, 'Bob'],
[2, 25, 'John'],
[2, 15, 'Bob']], columns = ['IssueKey','TimeSpent','User'])
IssueKey TimeSpent User
0 1 10 John
1 1 20 John
2 1 30 Tom
3 1 10 Bob
4 2 25 John
5 2 15 Bob
这里的索引只有1级(每一行只有一个索引值)。索引是人工的(运行 数字),由 0 到 5 的值组成。
假设我们要将同一用户创建的所有日志合并(求和)到同一问题(以获得总时间用户在该问题上的花费)
time_logged_by_user = report.groupby(['IssueKey', 'User']).TimeSpent.sum()
IssueKey User
1 Bob 10
John 30
Tom 30
2 Bob 15
John 25
现在我们的数据索引有 2 个级别,因为多个用户记录了同一问题的时间。级别为 IssueKey
和 User
。级别是索引的一部分(只有它们一起才能识别 DataFrame / Series 中的一行)。
级别作为索引的一部分(作为元组)可以在 Spyder 变量浏览器中很好地观察到:
拥有级别让我们有机会根据我们选择的索引部分 (level) 在组内聚合值。例如。如果我们想分配任何用户在某个问题上花费的最长时间,我们可以:
max_time_logged_to_an_issue = time_logged_by_user.groupby(level='IssueKey').transform('max')
IssueKey User
1 Bob 30
John 30
Tom 30
2 Bob 25
John 25
现在前 3 行的值为 30
,因为它们对应于问题 1
(User
级别在上面的代码中被忽略)。问题 2
.
同样的故事
这可能很有用,例如如果我们想找出哪些用户在每个问题上花费的时间最多:
issue_owners = time_logged_by_user[time_logged_by_user == max_time_logged_to_an_issue]
IssueKey User
1 John 30
Tom 30
2 John 25
我一直在阅读文档,许多解释和示例都使用 levels
作为理所当然的东西。恕我直言,文档缺乏对数据结构和定义的基本解释。
数据框中的级别是什么? MultiIndex
索引中的级别是什么?
通常一个 DataFrame 有一个一维索引和列:
x y
0 4 1
1 3 9
此处索引为 [0, 1],列为 ['x', 'y']。但是您可以在索引或列中有多个级别:
x y
a b c
0 7 4 1 3
8 3 9 5
此处列的第一级是 ['x'、'y'、'y'],第二级是 ['a'、'b'、'c']。索引的第一层是[0, 0],第二层是[7, 8].
我在分析
简答:
级别是索引或列的一部分。
长答案:
我认为这个多列 DataFrame.groupby
示例很好地说明了索引级别。
假设我们有时间登录问题报告数据:
report = pd.DataFrame([
[1, 10, 'John'],
[1, 20, 'John'],
[1, 30, 'Tom'],
[1, 10, 'Bob'],
[2, 25, 'John'],
[2, 15, 'Bob']], columns = ['IssueKey','TimeSpent','User'])
IssueKey TimeSpent User
0 1 10 John
1 1 20 John
2 1 30 Tom
3 1 10 Bob
4 2 25 John
5 2 15 Bob
这里的索引只有1级(每一行只有一个索引值)。索引是人工的(运行 数字),由 0 到 5 的值组成。
假设我们要将同一用户创建的所有日志合并(求和)到同一问题(以获得总时间用户在该问题上的花费)
time_logged_by_user = report.groupby(['IssueKey', 'User']).TimeSpent.sum()
IssueKey User
1 Bob 10
John 30
Tom 30
2 Bob 15
John 25
现在我们的数据索引有 2 个级别,因为多个用户记录了同一问题的时间。级别为 IssueKey
和 User
。级别是索引的一部分(只有它们一起才能识别 DataFrame / Series 中的一行)。
级别作为索引的一部分(作为元组)可以在 Spyder 变量浏览器中很好地观察到:
拥有级别让我们有机会根据我们选择的索引部分 (level) 在组内聚合值。例如。如果我们想分配任何用户在某个问题上花费的最长时间,我们可以:
max_time_logged_to_an_issue = time_logged_by_user.groupby(level='IssueKey').transform('max')
IssueKey User
1 Bob 30
John 30
Tom 30
2 Bob 25
John 25
现在前 3 行的值为 30
,因为它们对应于问题 1
(User
级别在上面的代码中被忽略)。问题 2
.
这可能很有用,例如如果我们想找出哪些用户在每个问题上花费的时间最多:
issue_owners = time_logged_by_user[time_logged_by_user == max_time_logged_to_an_issue]
IssueKey User
1 John 30
Tom 30
2 John 25