我想根据索引为我的数据框创建一个子索引。例如,我有这样一个数据帧:熊猫:如何高效创建子索引?
Content Date
ID
Bob birthday 2010.03.01
Bob school 2010.04.01
Tom shopping 2010.02.01
Tom work 2010.09.01
Tom holiday 2010.10.01
我想创建一个分类指数为我ID
,并将所得数据框看起来象下面这样:
Content Date
ID subindex
Bob 1 birthday 2010.03.01
2 school 2010.04.01
Tom 1 shopping 2010.02.01
2 work 2010.09.01
3 holiday 2010.10.01
要做到这一点,我需要先创建我的subindex
列表。我搜索的帮助文档中,它似乎最简洁的方式是使用transform
:
subindex = df['Date'].groupby(df.index).transform(lambda x: np.arange(1, len(x) + 1))
然而,这实在是太慢了。我环顾四周,发现apply
可以做的工作太多:
subindex = df['Date'].groupby(df.index).apply(lambda x: np.arange(1, len(x) + 1))
当然需要subindex
被夷为平地,因为它是一个列表的列表在这里。这种方法比transform
方法快得多。然后我用我自己的for loop
进行测试:
subindex_size = df.groupby(df.index, sort = False).size()
subindex = []
for i in np.arange(len(subindex_size)):
subindex.extend(np.arange(1,subindex_size[i]+1))
它更快。使用我的大型数据集(大约90k行),transform
方法在我的电脑上大约需要44秒,apply
需要大约2秒,而for loop
只需要大约1秒。我需要处理更大的数据集,因此即使apply
和for loop
之间的时差对我也有所帮助。但是,如果我需要创建其他基于组的变量,则for loop
看起来很难看,并且可能不容易应用。
所以我的问题是,为什么应该做正确的事情的内置函数更慢?我在这里错过了什么,或者有这个理由吗?有没有其他方法可以改善这个过程?
我觉得应该有一个更好的API来追加一个水平提高到一个多指标......不觉得有(又)。 –
谢谢! 'cumcount'很好地工作!然而'set_index'似乎不适合我。我从字面上复制了'12'和'13'行,但'set_index'被程序忽略,这很奇怪。我必须使用df.index来重置索引。但是'cumcount'比上面提到的任何方法都快得多! –
@ ZhenSun你需要做的:'df = df.set_index('subindex',append = True)',或'df.set_index('subindex',append = True,inplace = True)'实际改变df! –