2017-11-26 1 views
2

bei gegebener 1xN Dataframe-Tabelle zurück, wählen Sie 5 größte Werte aus der Zeile und geben Sie die entsprechenden Spaltennamen in eine Liste ein. ist dies der Datenrahmen Beispiel:Geben Sie die Spaltennamen als Liste im Datenframe für eine gegebene Bedingung von Werten in python

  5  2   13   15   37  8   89  
PageRank 0.444384 0.44453 0.444695 0.444882 0.444759 0.44488 0.444648 

dies versucht haben,

r = list(pr.loc['PageRank'].nlargest(5)) 

aber die Liste erstellt hat nur die Werte in den Zeilen, nicht die Spaltennamen. Wie erhält man die Spaltennamen von 5 größten Zellenwerten? zum Beispiel in der gegebenen Datenrahmen, sollte es zurückgeben

[15,37,13,89,5] 

Antwort

1

Verwendung index:

r1 = list(pr.loc['PageRank'].nlargest(5).index) 
print (r1) 
[15, 8, 37, 13, 89] 

Oder:

r1 = pr.columns[pr.loc['PageRank'].values.argsort()][-1:-6:-1].tolist() 
print (r1) 
[15, 8, 37, 13, 89] 
5

Sie können mithilfe Numpy der np.argpartition einige zusätzliche Leistung. Ich werde es auf das Negative der Werte verwenden, um die richtige Richtung zu bekommen.

Ich wollte np.argpartition anstelle der Sortierung verwenden, weil es O(n) anstatt Sortieren ist, die O(nlogn) ist.

cols = pr.columns.values 
rnks = -pr.values[0] 
cols[np.argpartition(rnks, 5)[:5]].tolist() 

['37', '15', '13', '8', '89'] 

Zeit
werden Sie, dass pir1 übertrifft bemerken. Beachten Sie aber auch, dass sich nlargest asymptotisch der Leistung von pir1 nähert, da sie beide O(n) sind.

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) 

enter image description here

Taktverhältnis
Diese Tabelle zeigt das Verhältnis jeder Zeit relativ Methode auf das Minimum für die bestimmte Länge des Arrays benötigte Zeit.

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 
+0

Dies wird erwartet, wenn das Array groß genug ist, dass es innerhalb der ersten 5 Ränge immer eine Gleichheit gibt. – piRSquared

+0

Du bist besser innumpy wie ich, also keine Ahnung, was falsch ist, aber in größeren Datenrahmen ist das Problem. – jezrael

+0

Ich verstehe nicht, also ist die Lösung in Ordnung? Ich teste es in kleinen zufälligen Dataframes mit 30, 50 Spalten und manchmal die gleiche Ausgabe wie 'nlargest', manchmal nicht. Kannst du mehr erklären? Vielen Dank. – jezrael

Verwandte Themen