给定1xN数据帧表,需要从行中选取5个最大值并将相应的列名返回到列表中。 这是数据框样本:
5 2 13 15 37 8 89
PageRank 0.444384 0.44453 0.444695 0.444882 0.444759 0.44488 0.444648
尝试了这个,
r = list(pr.loc['PageRank'].nlargest(5))
但创建的列表只包含行中的值,而不是列名。 如何获取5个最大单元格值的列名? 例如,在给定的数据帧中,它应该返回
[15,37,13,89,5]
答案 0 :(得分:6)
使用Numpy的np.argpartition
可以获得一些额外的性能。我会在值的负数上使用它以获得正确的方向。
我想使用np.argpartition
而不是排序,因为它是O(n)
而不是排序O(nlogn)
。
cols = pr.columns.values
rnks = -pr.values[0]
cols[np.argpartition(rnks, 5)[:5]].tolist()
['37', '15', '13', '8', '89']
<强>时序强>
您会注意到pir1
表现优异。但请注意nlargest
渐近接近pir1
的效果,因为它们都是O(n)
。
jez1 = lambda d: list(d.loc['PageRank'].nlargest(5).index)
jez2 = lambda d: d.columns[d.loc['PageRank'].values.argsort()[::-1]][:5].tolist()
jez3 = lambda d: d.columns[d.loc['PageRank'].values.argsort()[-1:-6:-1]].tolist()
pir1 = lambda d: d.columns.values[np.argpartition(-d.values[0], 5)[:5]].tolist()
res = pd.DataFrame(
index=[10, 30, 100, 300, 1000, 3000, 10000, 30000, 100000, 300000, 1000000],
columns='jez1 jez2 jez3 pir1'.split(),
dtype=float
)
for i in res.index:
d = pd.DataFrame(dict(PageRank=np.random.rand(i))).T
for j in res.columns:
stmt = '{}(d)'.format(j)
setp = 'from __main__ import d, {}'.format(j)
res.at[i, j] = timeit(stmt, setp, number=200)
res.plot(loglog=True)
时间比率
此表显示了每种方法的时间相对于该特定数组长度所用的最短时间的比率。
res.div(res.min(1), 0)
jez1 jez2 jez3 pir1
10 20.740497 8.666576 6.738210 1.0
30 39.325125 11.962184 10.987012 1.0
100 30.121521 10.184435 10.173252 1.0
300 58.544734 11.963354 12.563072 1.0
1000 63.643729 9.361290 8.547374 1.0
3000 22.041026 15.977949 18.803516 1.0
10000 9.254778 11.620570 11.681464 1.0
30000 2.838243 7.522210 7.120721 1.0
100000 1.814005 7.486602 6.995017 1.0
300000 1.920776 13.213261 12.423890 1.0
1000000 1.332265 7.872120 7.225150 1.0
答案 1 :(得分:2)
使用index
:
r1 = list(pr.loc['PageRank'].nlargest(5).index)
print (r1)
[15, 8, 37, 13, 89]
或者:
r1 = pr.columns[pr.loc['PageRank'].values.argsort()][-1:-6:-1].tolist()
print (r1)
[15, 8, 37, 13, 89]