给定 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]
最佳答案
您可以使用 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
关于python-2.7 - 对于 python 中给定的值条件,将列名称作为数据框中的列表返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47493567/