Python 按数据降序对熊猫系列进行排序,然后按索引字母顺序优雅地排序

Python 按数据降序对熊猫系列进行排序,然后按索引字母顺序优雅地排序,python,python-3.x,pandas,sorting,numpy,Python,Python 3.x,Pandas,Sorting,Numpy,我正在寻找一种平滑的方法,通过数据降序,然后索引升序对熊猫系列进行排序。我在文档和Stackoverflow上四处寻找,但找不到一个简单的方法 该系列大约有5000个条目,是使用NLTK进行tf idf分析的结果 然而,下面我提供了一个非常小的数据样本来说明这个问题 import pandas as pd index = ['146tf150p', 'anytime', '645', 'blank', 'anything'] tfidf = [1.000000, 1.000000, 1.000

我正在寻找一种平滑的方法,通过数据降序,然后索引升序对熊猫系列进行排序。我在文档和Stackoverflow上四处寻找,但找不到一个简单的方法

该系列大约有5000个条目,是使用NLTK进行tf idf分析的结果

然而,下面我提供了一个非常小的数据样本来说明这个问题

import pandas as pd

index = ['146tf150p', 'anytime', '645', 'blank', 'anything']
tfidf = [1.000000, 1.000000, 1.000000, 0.932702, 1.000000]

tfidfmax = pd.Series(tfidf, index=index)
现在我只是将序列转换为数据帧,重置索引,进行排序,然后设置索引,但我觉得这是一个很大的迂回

frame = pd.DataFrame(tfidfmax , columns=['data']).reset_index().sort_values(['data','index'], ascending=[False, True]).set_index(['index'])
3.02 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我期待着你的建议

您可以使用:

res = tfidfmax[np.lexsort((tfidfmax.index, -tfidfmax.values))]

print(res)

# 146tf150p    1.000000
# 645          1.000000
# anything     1.000000
# anytime      1.000000
# blank        0.932702
# dtype: float64
注意语法的相反顺序:上面的代码首先按降序排列,然后按索引升序排列。

简单:

In [15]: pd.Series(tfidfmax.sort_values(ascending=False),index=tfidfmax.sort_index().index)
Out[15]: 
146tf150p    1.000000
645          1.000000
anything     1.000000
anytime      1.000000
blank        0.932702
dtype: float64
或更快的方式:

In [26]: pd.Series(-np.sort(-tfidfmax),index=np.sort(tfidfmax.index))
Out[26]: 
146tf150p    1.000000
645          1.000000
anything     1.000000
anytime      1.000000
blank        0.932702
dtype: float64

In [17]: %timeit tfidfmax[np.lexsort((tfidfmax.index, -tfidfmax.values))]
10000 loops, best of 3: 104 µs per loop

In [18]: %timeit pd.Series(tfidfmax.sort_values(ascending=False),index=tfidfmax.sort_index().index)
1000 loops, best of 3: 406 µs per loop

In [27]: %timeit pd.Series(-np.sort(-tfidfmax),index=np.sort(tfidfmax.index))
10000 loops, best of 3: 91.2 µs per loop

使用函数
sorted
by
zip
both
list
s创建新的
系列
by:


虽然是最快的解决方案,但要小心,这是错误的。请尝试检查我的答案中的数据。@Steven Van Dorpe的主要问题是,如果将我的答案中的数据更改为
tfidf=[1.000000,1.000000,2.000000,0.932702,2.000000]
,并将您的输入与此答案的输入进行比较,则存在差异。因为这个答案将索引和值分开排序。我尝试了这个答案,但它确实不能处理更复杂的数据。谢谢你指出这个@jezrael!谢谢我不知道这个裸体特征。还测试了速度:%timeit tfidfmax[np.lexsort((tfidfmax.index,-tfidfmax.values))]。每个回路211µs±6.86µs(7次运行的平均±标准偏差,每个1000个回路),谢谢!角度不错。您知道是否有某种方法可以使用sort_值并引用索引吗?即tfidf.sort_值(引用值,引用索引,升序=[False,True])。有点像lexsort,但在pandas内部。@Steven Van Dorpe遗憾的是还没有实现。
index = ['146tf150p', 'anytime', '645', 'blank', 'anything']
tfidf = [1.000000, 1.000000, 2.000000, 0.932702, 2.000000]

a = list(zip(*sorted(zip(index, tfidf),key=lambda x:(-x[1],x[0]))))

#if input is Series
#a = list(zip(*sorted(zip(tfidfmax.index,tfidfmax),key=lambda x:(-x[1],x[0]))))
s = pd.Series(a[1], index=a[0])
print (s)
645          2.000000
anything     2.000000
146tf150p    1.000000
anytime      1.000000
blank        0.932702
dtype: float64