2017-08-29 1 views
2

Ich habe einen Pandas-Datenrahmen mit Indizes zu einem numply-Array. Der Wert des Arrays muss für diese Indizes auf 1 gesetzt werden. Ich muss dies millionenfach auf einem großen Array tun. Gibt es einen effizienteren Weg als der unten gezeigte Ansatz?mit Pandas Datenrahmen, um Indizes in numpy Array setzen

from numpy import float32, uint 
from numpy.random import choice 
from pandas import DataFrame 
from timeit import timeit 

xy = 2000,300000 
sz = 10000000 
ind = DataFrame({"i":choice(range(xy[0]),sz),"j":choice(range(xy[1]),sz)}).drop_duplicates() 
dtype = uint 
repeats = 10 

#original (~21s) 
stmt = '''\ 
from numpy import zeros 
a = zeros(xy, dtype=dtype) 
a[ind.values[:,0],ind.values[:,1]] = 1''' 

print(timeit(stmt, "from __main__ import xy,sz,ind,dtype", number=repeats)) 

#suggested by @piRSquared (~13s) 
stmt = '''\ 
from numpy import ones 
from scipy.sparse import coo_matrix 
i,j = ind.i.values,ind.j.values 
a = coo_matrix((ones(i.size, dtype=dtype), (i, j)), dtype=dtype).toarray() 
''' 

print(timeit(stmt, "from __main__ import xy,sz,ind,dtype", number=repeats)) 

Ich habe den oben genannten Post bearbeitet den Ansatz zu zeigen (n) vorgeschlagen von @piRSquared und wieder schrieb er ein Äpfel mit Äpfeln verglichen zu ermöglichen. Ungeachtet des Datentyps (probiert uint und float32) hat der vorgeschlagene Ansatz eine 40% ige Reduzierung der Zeit.

Antwort

5

OP Zeit

56.56 s 

I

i, j = ind.i.values, ind.j.values 
a[i, j] = 1 

New Time

52.19 s 

jedoch nur marginal verbessern mit, können Sie dies erheblich beschleunigen, indem Sie mit bis scipy.sparse.coo_matrix zu instanziieren als Matrix analysieren und dann in eine numpy.array konvertieren.

import timeit 

stmt = '''\ 
import numpy, pandas 
from scipy.sparse import coo_matrix 

xy = 2000,300000 

sz = 10000000 
ind = pandas.DataFrame({"i":numpy.random.choice(range(xy[0]),sz),"j":numpy.random.choice(range(xy[1]),sz)}).drop_duplicates() 

################################################ 
i, j = ind.i.values, ind.j.values 
dtype = numpy.uint8 
a = coo_matrix((numpy.ones(i.size, dtype=dtype), (i, j)), dtype=dtype).toarray()''' 

timeit.timeit(stmt, number=10) 

33.06471237000369 
+0

Ja ... ein kleines bisschen. Sie verzichten auf den Aufwand für die Erstellung des Arrays 'ind1'. 'ind.i.values' und' ind.j.values' sind bereits da. 'ind.values' ist nicht und wird erstellt. – piRSquared

+1

@jezrael neue zeit. – piRSquared

+0

danke @piRSquared. Ich habe den ursprünglichen Beitrag aktualisiert, um Ihre Methode zu zeigen und einfach zu vergleichen. – ironv

Verwandte Themen