按照索引自然排序pandas DataFrame

4

我的数据框是这样的形式

                       material
15N                    649.7
16S                    703.2
16N                    711.7
1S                     716.2
1N                     724.5
2S                     723.5
2N                     721.5

我想按照前两个数字而不是第一个数字对索引进行排序,我使用的代码如下:
runn1.sort_index(axis=0, inplace=True) 

它按照第一个数字排序,而不是前两个数字,我希望数据变成这样

    1S                     716.2
    1N                     724.5
    2S                     723.5
    2N                     721.5
    15N                    649.7
    16S                    703.2
    16N                    711.7

我试图按照"S"和"N"之前的数字进行排序,如果有并列的情况,我希望以以"S"结尾的数字排在前面。所以在上面的例子中,"1S"排在"1N"之前。

如何获取这种数据格式?

2个回答

3

使用 natsortedreindex 进行排序

from natsort import natsorted
df.reindex(natsorted(df.index))
     material
1N      724.5
1S      716.2
2N      721.5
2S      723.5
15N     649.7
16N     711.7
16S     703.2

更新
l=sorted(df.index.str.split('(\d+)([A-z]+)').tolist(), key = lambda x: (-int(x[1]), x[2]))
df.reindex([''.join(x) for x in l ]).iloc[::-1]
     material
1S      716.2
1N      724.5
2S      723.5
2N      721.5
15N     649.7
16S     703.2
16N     711.7

在带有相同数字的标签中,“N”和“S”的顺序很重要,因此您需要一个“关键字”(请参见我的答案)。 - cs95
1
@coldspeed 是的,已经修复了 :-) - BENY

1
为了满足额外的要求,即所有"S"都在"N"之前,请使用natsort模块,并向natsorted传递一个key=...参数。
natsorted(df.index, lambda x: (x[:-1], x[-1] == 'N'))
# ['1S', '1N', '2S', '2N', '15N', '16S', '16N']    
df.loc[natsorted(df.index, lambda x: (x[:-1], x[-1] == 'N'))]
     material
1S      716.2
1N      724.5
2S      723.5
2N      721.5
15N     649.7
16S     703.2
16N     711.7

natsort 更加通用于自然排序问题,是这种情况下的一个方便工具。可以使用 PyPi 进行安装。


如果"S"和"N"的顺序不重要,考虑使用argsort来提高性能:
df.iloc[df.index.str[:-1].astype(int).argsort()]

或者,
df.iloc[np.argsort([int(x[:-1]) for x in df.index])]

     material
1S      716.2
1N      724.5
2S      723.5
2N      721.5
15N     649.7
16S     703.2
16N     711.7

非常感谢。如果我让最后一个字符S始终在N前面,如1S 1N 2S 2N 15N 16S 16N这样排序,我们该如何使用这个排序呢? - maryadi
@maryadi 请编辑您的问题,将其作为解决问题的要求,并且我会编辑我的答案并提供一个解决方案。 - cs95
我使用了第一种方法,但它仍然在索引的第一个数字上排序,这是我的问题所在? - maryadi
argsort()不是函数,但natsort将N放在前面,如何将S放在前面呢? - maryadi
@maryadi,希望你看到了我的编辑答案,其中展示了如何使用natsort将S放在N之前。如果你想要改变它,请使用df.loc[natsorted(df.index, lambda x: (x[:-1], x[-1] != 'N'))]。使用适合你的任何一个。 - cs95
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接