4 Stimmen

Was passiert mit Numpy/Scipy-Zeigern, wenn sie in eine lokale Variable kopiert werden?

Ich bin mir bewusst, dass Numpy-Arrays Zeiger-Arrays sind. Und ich weiß, dass es möglich ist, Zeiger in Python zu definieren. Aber ich frage mich, wenn ich eine Variable gleich einem Element in einem Numpy-Vektor, ist es immer noch ein Zeiger oder ist es de-referenced? Gibt es eine Möglichkeit, dies herauszufinden oder zu testen?

Beispiel

    import scipy
    vec = scipy.randn(10)
    vecptr = vec # vecptr is a pointer to vec
    vecval = scipy.copy(vec) # vecval is not a pointer.

    var = vec[3] # is var pointer or is it copied by value ???

    print(type(var)) # returns numpy.float64.  does this mean its a 1x1 numpy vec and therefore  a pointer ?

Der Grund, warum ich frage, ist, was ich wirklich wissen möchte, ist; wird der unten stehende Code meinen Speicher verdoppeln? Ich versuche, aussagekräftigere Variablennamen für meinen Vektor zu erstellen, der zurückgegeben wird

    v = self.viewCoefs[sz][sv][sa]

    gw = v[0]
    G0 = v[1]
    G1 = v[2]
    G2 = v[3]
    alpha0 = v[4]
    alpha1 = v[5]
    alpha2 = v[6]
    beta0 = v[7]
    beta1 = v[8]
    beta2 = v[9]
    beta3 = v[10]
    gamma0 = v[11]
    gamma1 = v[12]
    gamma2 = v[12]
    gamma3 = v[12]
    gamma4 = v[13]
    delta0 = v[14]
    delta1 = v[15]
    delta2 = v[16]
    delta3 = v[17]
    delta4 = v[18]
    delta5 = v[19]
    zeta_prime_0 = v[20]
    zeta_prime_1 = v[21]
    zeta_prime_2 = v[22]
    Gamma_prime_0 = v[23]
    Gamma_prime_1 = v[24]
    Gamma_prime_2 = v[25]
    Gamma_prime_3 = v[26]

Weil ich viele davon zu befolgen habe

    p0 = alpha0 + alpha1*scipy.log(bfrac) + alpha2*scipy.log(bfrac)**2
    p1 = beta0 + beta1*scipy.log(bfrac) + beta2*scipy.log(bfrac)**2 + beta3*scipy.log(bfrac)**3
    p2 = gamma0 + gamma1*scipy.log(bfrac) + gamma2*scipy.log(bfrac)**2 + gamma3*scipy.log(bfrac)**3 + gamma4*scipy.log(bfrac)**4
    p3 = delta0 + delta1*scipy.log(bfrac) + delta2*scipy.log(bfrac)**2 + delta3*scipy.log(bfrac)**3 + delta4*scipy.log(bfrac)**4 + delta5*scipy.log(bfrac)**5

    subSurfRrs = g*(p0*u + p1*u**2 + p2*u**3 + p3*u**4)
    ## and lots more

Ich möchte also aussagekräftige Variablennamen, ohne meinen Speicherplatz zu verdoppeln.

#

Okay, wenn ich es richtig verstanden habe, ist die Lösung, um meinen Speicher nicht zu verdoppeln, :

    v = self.veiwCoefs[sz][sv][sa]

    gw = v[0:1]
    G0 = v[1:2]
    G1 = v[2:1]
    alpha0 = v[3:4]
    alpha1 = v[4:5]
    alpha2 = v[5:6]
    beta0 = v[6:7]
    beta1 = v[7:8]
    beta2 = v[8:9]
    beta3 = v[9:10]
    ## etc 

    p0 = alpha0[0] + alpha1*scipy.log(bfrac) + alpha2[0]*scipy.log(bfrac)**2
    p1 = beta0[0] + beta1[0]*scipy.log(bfrac) + beta2[0]*scipy.log(bfrac)**2 + beta3[0]*scipy.log(bfrac)**3

    ## etc

4voto

JoshAdel Punkte 62773

Sie haben es fast, aber hier ist, wie man eine Ansicht eines einzelnen Elements zu erstellen:

In [1]: import numpy as np

In [23]: v = np.arange(10)

In [24]: a = v[3:4]

In [25]: a[0] = 100

In [26]: v
Out[26]: array([  0,   1,   2, 100,   4,   5,   6,   7,   8,   9])

Hier a ist eine Ansicht des vierten Elements von v wenn Sie also die a ändern Sie die entsprechende Position in v .

1voto

Bi Rico Punkte 24493

Ansichten sind sehr nützlich, und wenn man sie gut einsetzt, kann man eine Menge Speicherplatz sparen, aber in Ihrem Fall halte ich Ansichten nicht für angemessen. Während eine Ansicht die zugrunde liegenden Daten wiederverwendet, würde ich sie nicht als Zeiger bezeichnen. Jede Ansicht ist ein einzigartiges ndarray-Objekt, das heißt, es hat seine eigenen Eigenschaften, zum Beispiel Form:

In [4]: a = np.arange(7)

In [5]: b = a[1:5]

In [6]: b.shape = (2,2)

In [7]: b
Out[7]: 
array([[1, 2],
       [3, 4]])
In [8]: a.shape
Out[8]: (7,)

wenn Sie also b = a[0:1] erstellen Sie ein brandneues ndarray-Objekt, um ein int/float/... oder was auch immer zu speichern. Wenn Sie möchten, dass Sie sinnvolle Namen für jedes Element Ihres Arrays haben, werden Sie wahrscheinlich nicht viel effizienter sein als:

v = self.viewCoefs[sz][sv][sa]

gw = v[0]
G0 = v[1]
G1 = v[2]
G2 = v[3]
alpha0 = v[4]
## etc

Das heißt, Sie sollten versuchen, Ihren Code als Operationen auf Arrays zu schreiben, anstatt als Operationen auf Elemente von Arrays. Zum Beispiel könnten Sie schreiben:

coefs = np.zeros((5,5))
lt = np.tril_indices(5)
coefs[lt] = self.viewCoefs[sz][sv][sa]

p = (coefs * scipy.log(bfrac)**[1, 2, 3, 4, 5]).sum(-1)
subSurfRrs = g*(p*u**[1, 2, 3, 4]).sum()

Vektorisierter Code kann bei Verwendung von Numpy viel schneller sein. In diesem Fall nutzen wir auch das Broadcasting von numpy, das ich für sehr verwirrend hielt, bis ich es ein wenig besser kennenlernte und erkannte, wie nützlich es sein kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X