按照字母顺序,优雅地对数据进行排序,然后对索引进行排序

时间:2018-04-13 10:28:43

标签: python python-3.x pandas sorting numpy

我正在寻找一种顺畅的方法来按数据降序对pandas系列进行排序,然后是索引升序。我一直在浏览文档和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)

现在我只是将系列转换为DataFrame,重置索引,进行排序然后设置索引,但我觉得这是一个很大的弯路。

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)

我期待你的建议!

编辑24/04 - 解决方案摘要:

使用Numpy lexsort:

%timeit tfidfmax[np.lexsort((tfidfmax.index, -tfidfmax.values))]
261 µs ± 9.27 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

使用已排序()和压缩列表

def a():
    a = list(zip(*sorted(zip(index, tfidf),key=lambda x:(-x[1],x[0]))))
    pd.Series(a[1], index=a[0])
%timeit a() 
203 µs ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

3 个答案:

答案 0 :(得分:3)

sorted zip使用list功能Serieszip创建新的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

kotlin_version = '1.2.31'

答案 1 :(得分:2)

您可以使用numpy.lexsort

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

请注意语法中的相反顺序:上面的代码首先按降序值排序,然后按索引升序排序。

答案 2 :(得分:1)

简单:

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
相关问题