首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Pandas多重索引中重置单个索引?

问如何在Pandas多重索引中重置单个索引?
EN

Stack Overflow用户
提问于 2021-10-27 16:13:23
回答 3查看 111关注 0票数 2

我有一个由多个数据文件构建的MultiIndex DataFrame,我需要重置第一个索引。除了第一个索引之外,我什么也不想改变;其他所有东西的整个结构和顺序都应该保持不变。

我现在的情况是这样的:

代码语言:javascript
复制
index = pd.MultiIndex.from_tuples([('0', 'Albert'),
                                   ('0', 'Isaac'),
                                   ('0', "Charles"),
                                   ('1', 'James'),
                                   ('1', 'Paul'),
                                   ('0', 'Wolfgang'),
                                   ('0', 'Enrico'),
                                   ('0', "John"),
                                   ('1', 'Marie'),
                                   ('1', 'Carol'),
                                   ('2', "Solomon"),
                                   ("2", "Joseph"),
                                   ("2", "Phil"),
                                   ('2', 'Danielle')],
                                  names=['class', 'name'])
columns = ('High', 'Average')
df = pd.DataFrame([(98.8, 97.9),
                   (100.0, 99.9),
                   (76.5, 64.2),
                   (99.3, 98.9),
                   (87.2, 83.3),
                   (98.8, 96.5),
                   (100.0, 97.7),
                   (88.6, 64.2),
                   (99.3, 78.3),
                   (87.2, 81.0),
                   (78.8, 65.9),
                   (99.0, 95.4),
                   (86.1, 74.7),
                   (97.9, 91.1)],
                  index=index,
                  columns=columns)

这提供了一个如下所示的数据帧:

代码语言:javascript
复制
                 High  Average
class name                    
0     Albert     98.8     97.9
      Isaac     100.0     99.9
      Charles    76.5     64.2
1     James      99.3     98.9
      Paul       87.2     83.3
0     Wolfgang   98.8     96.5
      Enrico    100.0     97.7
      John       88.6     64.2
1     Marie      99.3     78.3
      Carol      87.2     81.0
2     Solomon    78.8     65.9
      Joseph     99.0     95.4
      Phil       86.1     74.7
      Danielle   97.9     91.1

我想要重置"class“索引,只从0开始,然后迭代到”class“中的最后一个条目。最终结果应该如下所示:

代码语言:javascript
复制
                 High  Average
class name                    
0     Albert     98.8     97.9
      Isaac     100.0     99.9
      Charles    76.5     64.2
1     James      99.3     98.9
      Paul       87.2     83.3
2     Wolfgang   98.8     96.5
      Enrico    100.0     97.7
      John       88.6     64.2
3     Marie      99.3     78.3
      Carol      87.2     81.0
4     Solomon    78.8     65.9
      Joseph     99.0     95.4
      Phil       86.1     74.7
      Danielle   97.9     91.1

我不知道如何做到这一点;我尝试过使用reindex,set_levels,还有一些其他的东西。我觉得这应该是一件很简单的事情,所以我必须在内置函数的选项中遗漏一些东西(这将是我最喜欢的方法,但即使是在这一点上“讨厌”的东西也足够了!)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-27 16:27:01

从第一个索引级别创建一个新索引,然后与第二个索引合并,并将其设置为新索引:

代码语言:javascript
复制
import numpy as np

idx = df.index.get_level_values('class')
new_idx = pd.Index((idx != np.roll(idx, 1)).cumsum() -1, name='class')

df = df.set_index(pd.MultiIndex.from_arrays(
                      [new_idx, df.index.get_level_values('name')]))
代码语言:javascript
复制
>>> df
                 High  Average
class name                    
0     Albert     98.8     97.9
      Isaac     100.0     99.9
      Charles    76.5     64.2
1     James      99.3     98.9
      Paul       87.2     83.3
2     Wolfgang   98.8     96.5
      Enrico    100.0     97.7
      John       88.6     64.2
3     Marie      99.3     78.3
      Carol      87.2     81.0
4     Solomon    78.8     65.9
      Joseph     99.0     95.4
      Phil       86.1     74.7
      Danielle   97.9     91.1

用@It_is_Chris改进的解决方案

详细信息:

代码语言:javascript
复制
>>> idx.tolist()
['0', '0', '0', '1', '1', '0', '0', '0', '1', '1', '2', '2', '2', '2']

>>> np.roll(idx, 1).tolist()
['2', '0', '0', '0', '1', '1', '0', '0', '0', '1', '1', '2', '2', '2']

现在比较两个列表中的每个元素:'0' != '2','0' != '0',直到'2' != '2'。你有一个布尔面具

代码语言:javascript
复制
>>> (idx != np.roll(idx, 1)).tolist()
[True, False, False, True, False, True, False,
 False, True, False, True, False, False, False]

在此布尔掩码上应用累加和减去1,以获得新索引:

代码语言:javascript
复制
>>> ((idx != np.roll(idx, 1)).cumsum() - 1).tolist()
[0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4]

现在用新索引和第二层重新构建索引:

代码语言:javascript
复制
>>> pd.MultiIndex.from_arrays([new_idx, df.index.get_level_values('name')])
MultiIndex([(0,   'Albert'),
            (0,    'Isaac'),
            (0,  'Charles'),
            (1,    'James'),
            (1,     'Paul'),
            (2, 'Wolfgang'),
            (2,   'Enrico'),
            (2,     'John'),
            (3,    'Marie'),
            (3,    'Carol'),
            (4,  'Solomon'),
            (4,   'Joseph'),
            (4,     'Phil'),
            (4, 'Danielle')],
           names=['class', 'name'])
票数 2
EN

Stack Overflow用户

发布于 2021-10-27 16:19:49

一种选择是

代码语言:javascript
复制
df = df1.reset_index()
df['class'] = df['class'].astype(int).diff().fillna(0).ne(0).cumsum().astype(int)
df = df.set_index(['class', 'name'])
>>> df
                index   High  Average
class name                           
0     Albert        0   98.8     97.9
      Isaac         1  100.0     99.9
      Charles       2   76.5     64.2
1     James         3   99.3     98.9
      Paul          4   87.2     83.3
2     Wolfgang      5   98.8     96.5
      Enrico        6  100.0     97.7
      John          7   88.6     64.2
3     Marie         8   99.3     78.3
      Carol         9   87.2     81.0
4     Solomon      10   78.8     65.9
      Joseph       11   99.0     95.4
      Phil         12   86.1     74.7
      Danielle     13   97.9     91.1

这也不适用于索引,因此它是在class列的某些更改之前和之后设置的。

注释

在我的第一次尝试中,我使用了这样的方法:

代码语言:javascript
复制
df = df.reset_index()
df['class'] = df['class'].astype(int).diff().abs().cumsum().fillna(0).astype(int)
df = df.set_index(['class', 'name'])

这将为给定的示例生成正确的结果,因为“类”-column中的差异仅为-1或1.If --与-1、0或1不同,这将导致错误的结果。

票数 2
EN

Stack Overflow用户

发布于 2021-10-27 16:29:22

一种选择是重置索引,然后在其中创建组,然后再重新索引。

代码语言:javascript
复制
df2 = df.reset_index()
df2['class'] = (df2['class'] != df2['class'].shift()).cumsum() - 1
df = df2.set_index(['class', 'name'])
>>>
                 High  Average
class name
0     Albert     98.8     97.9
      Isaac     100.0     99.9
      Charles    76.5     64.2
1     James      99.3     98.9
      Paul       87.2     83.3
2     Wolfgang   98.8     96.5
      Enrico    100.0     97.7
      John       88.6     64.2
3     Marie      99.3     78.3
      Carol      87.2     81.0
4     Solomon    78.8     65.9
      Joseph     99.0     95.4
      Phil       86.1     74.7
      Danielle   97.9     91.1
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69742123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档