Toon posts:

numpy copy optimalisatie

Pagina: 1
Acties:

Vraag


  • htca
  • Registratie: November 2001
  • Nu online
Mijn vraag
Ik heb een lange 1 dimensional array (lengte > 1.5miljoen) die ik wil opsplitsen in verspringende arrays van lengte 600 en die plaatsen in een matrix. Om een idee te geven:

code:
1
2
3
4
5
6
7
8
9
10
# (lengte 1.5 miljoen of meer)
initial array = [1,2,4,6,4,3,7,8,9,34,47,8,2,....45,2,5,67] 

#matrix n x 600
matrix = [[1, 0, 0, 0,0 ,0, 0,....],
               [2,1,0,0,0,0,0,0,....],
               [4,2,1,0,0,0,0,0,....],
               [6,4,2,1,0,0,0,0,....],
....
]

Op zich kan middels numpy.copy() of rechtstreeks uit de array ([0:600], [1:601], etc even de starts en einde buiten beschouwing gelaten) halen en dat werkt. Maar qua performance duurt dat erg lang. Op zich niet erg, maar wel als je deze exercitie dan ook weer een aantal duizenden keren moet herhalen.
Om een idee te geven, de methode die ik nu gebruik duurt het vullen van de matrix in de orde van 15 tot 20 seconden. De code die ik nu gebruik (snippet):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        f_load = np.array(F_vector) # de lange vector

        n_location = 600 # locations in the model

        start = 0
        f_matrix = []
        while True:
            f_temp = np.zeros(n_location)
            if start < n_location:
                f_temp[0:start + 1] = f_load[0:start + 1][::-1]
            elif start >= n_location:
                f_temp[n_location-len(f_load[max(0,start-n_location-1):start-1][::-1]):n_location] = f_load[max(0,start-n_location-1):start-1][::-1]
            else:
                f_temp = f_load[max(0,start-n_location-1):start-1][::-1]
            if np.count_nonzero(f_temp) >0:
                f_matrix.append(np.array(f_temp))
            start += 1
            if start > n_location + len(f_load):
                break



Relevante software en hardware die ik gebruik
Ik gebruik python (3.6) en numpy in een pycharm omgeving

Wat ik al gevonden of geprobeerd heb
De oplossing zoals hierboven, maar ik zoek een optimalisatie van deze code.

Alle reacties


  • Gropah
  • Registratie: December 2007
  • Niet online

Gropah

Admin Softe Goederen

Oompa-Loompa 💩

Waarom gebruik je niet de split functie?

  • AGee
  • Registratie: December 2002
  • Niet online

AGee

Formerly known as naitsoezn

Of reshape. Edit: O wacht, de opdracht is iets complexer :P

[Voor 16% gewijzigd door AGee op 09-07-2020 10:01]

't Het nog nooit, nog nooit zo donker west, of 't wer altied wel weer licht


  • Gropah
  • Registratie: December 2007
  • Niet online

Gropah

Admin Softe Goederen

Oompa-Loompa 💩

Ah, check, het verspringende gedeelte gemist.

Ik denk dat je best wel wat tijd kunt besparen door de grootte van je matrix van te voren te alloceren. En als je zo vaak 0 in je data hebt kun je wellicht ook kijken naar sparse matrices? Maar wellicht ook handig om uit te leggen wat je wilt bereiken, want ik zou bijna denken dat je het jezelf te moeilijk maakt.

  • htca
  • Registratie: November 2001
  • Nu online
Gropah schreef op donderdag 9 juli 2020 @ 10:12:
Ah, check, het verspringende gedeelte gemist.

Ik denk dat je best wel wat tijd kunt besparen door de grootte van je matrix van te voren te alloceren. En als je zo vaak 0 in je data hebt kun je wellicht ook kijken naar sparse matrices? Maar wellicht ook handig om uit te leggen wat je wilt bereiken, want ik zou bijna denken dat je het jezelf te moeilijk maakt.
hmmm eens een poging wagen omdat uit te leggen.... (geef gerust aan als het niet duidelijk is)

Ik combineer 2 modellen waarmee superpositie mogelijk is.
In de ene berekening krijg ik als gevolg van een 600 unit belastingen een matrix van 600 x aantal punten (in de orde van 1000).

Uit de exercitie uit de topicstart krijg ik een matrix met x aantal situaties van 600 factoren (elke factor hoort bij een unit belasting) en kost relatief gezien veel tijd, meer dan 2/3 van de loop wordt hier gespendeerd. De lengte van de matrix zou op zich wel uit te rekenen zijn, maar wat ik nu doe is, dat ik eerst een array maak en dan de array toevoeg aan de matrix. Als ik alloceer moet ik de matrix in zijn geheel eerst opzetten (met 0) en dan rechtstreeks vullen denk ik?

Vervolgens loop ik door de matrix met x situaties en vermenigvuldig en tel de uitkomsten op om een verloop te krijgen over de 600 punten (np.matmul voor iedere situatie, wat overigens weer razendsnel gaat). Daarna doe ik de post-processing, figuren bouwen en verdere data analyse.

De matrices zijn niet (echt) sparse.

  • Gropah
  • Registratie: December 2007
  • Niet online

Gropah

Admin Softe Goederen

Oompa-Loompa 💩

htca schreef op donderdag 9 juli 2020 @ 11:05:
[...]
De lengte van de matrix zou op zich wel uit te rekenen zijn, maar wat ik nu doe is, dat ik eerst een array maak en dan de array toevoeg aan de matrix. Als ik alloceer moet ik de matrix in zijn geheel eerst opzetten (met 0) en dan rechtstreeks vullen denk ik?

[...]
Dat lijkt mij het handigste. Wat ik namelijk denk (maar wellicht handig om te verifieren) dat er gebeurd is dat voor elke array die je toevoegt hij een geheel nieuw stuk geheugen moet alloceren en dat kost redelijk wat tijd, elke keer weer. Dus als je van te voren kunt berekenen hoeveel elementen er in zitten en in 1 keer de ruimte kunt alloceren, bespaar je denk ik veel tijd.

De reden dat ik overigens vroeg naar wat je probeert is omdat met aanvullen met nullen etc je vaak dingen probeert te zoeken. En hoewel array comparisons sneller kunnen, kan het afhankelijk van wat je zoekt ook sneller met dingen zoals tries oid.

[Voor 14% gewijzigd door Gropah op 09-07-2020 11:20]


  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Volgens mij kan je in python wel spelen met lower triangular matrices... tril of tril_indices geeft je hopelijk wat handvatten.

Zoiets?
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
import math

import numpy as np

a=[1,2,3,4,5,6,7,8,9,10]

matrix_size=math.ceil(pow(len(a),1/2))

indices=np.tril_indices(matrix_size)

b=np.zeros(shape=(matrix_size,matrix_size))

b[indices]=a

[Voor 48% gewijzigd door KabouterSuper op 09-07-2020 11:46]


  • htca
  • Registratie: November 2001
  • Nu online
Gropah schreef op donderdag 9 juli 2020 @ 11:18:
[...]


Dat lijkt mij het handigste. Wat ik namelijk denk (maar wellicht handig om te verifieren) dat er gebeurd is dat voor elke array die je toevoegt hij een geheel nieuw stuk geheugen moet alloceren en dat kost redelijk wat tijd, elke keer weer. Dus als je van te voren kunt berekenen hoeveel elementen er in zitten en in 1 keer de ruimte kunt alloceren, bespaar je denk ik veel tijd.

De reden dat ik overigens vroeg naar wat je probeert is omdat met aanvullen met nullen etc je vaak dingen probeert te zoeken. En hoewel array comparisons sneller kunnen, kan het afhankelijk van wat je zoekt ook sneller met dingen zoals tries oid.
allocatie geeft een snelheidswinst van 2 tot 2.5 ongeveer 8) thanks!
KabouterSuper schreef op donderdag 9 juli 2020 @ 11:34:
Volgens mij kan je in python wel spelen met lower triangular matrices... tril of tril_indices geeft je hopelijk wat handvatten.
Ga ik ook nog even naar kijken!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
htca schreef op donderdag 9 juli 2020 @ 11:46:
[...]
Ga ik ook nog even naar kijken!
Ik heb een voorbeeldje in mijn vorige post toegevoegd. Die doet niet precies hetzelfde, maar geeft wel aan hoe je met indices kunt spelen.

Om precies te doen wat je wilt, moet je de indices van je list ook handig dupliceren. Hieronder een voorbeeld:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import math

import numpy as np

a=np.array([1.1,2.1,3.1,4.1,5.1,6.1])

matrix_size=len(a)

tri_low_matrix_indices=np.tril_indices(matrix_size)

repeated_indices=tri_low_matrix_indices[0]-tri_low_matrix_indices[1]

b=np.zeros(shape=(matrix_size,matrix_size))

b[tri_low_matrix_indices]=a[repeated_indices]

print(b)

[Voor 90% gewijzigd door KabouterSuper op 09-07-2020 13:12. Reden: Code nog wat efficienter gemaakt]


  • htca
  • Registratie: November 2001
  • Nu online
KabouterSuper schreef op donderdag 9 juli 2020 @ 11:46:
[...]

Ik heb een voorbeeldje in mijn vorige post toegevoegd. Die doet niet precies hetzelfde, maar geeft wel aan hoe je met indices kunt spelen.

Om precies te doen wat je wilt, moet je de indices van je list ook handig dupliceren. Hieronder een voorbeeld:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import math

import numpy as np

a=np.array([1.1,2.1,3.1,4.1,5.1,6.1])

matrix_size=len(a)

tri_low_matrix_indices=np.tril_indices(matrix_size)

repeated_indices=tri_low_matrix_indices[0]-tri_low_matrix_indices[1]

b=np.zeros(shape=(matrix_size,matrix_size))

b[tri_low_matrix_indices]=a[repeated_indices]

print(b)
Ik ga het weekend eens studeren.... thanks!
Pagina: 1



Google Pixel 7 Sony WH-1000XM5 Apple iPhone 14 Samsung Galaxy Watch5, 44mm Sonic Frontiers Samsung Galaxy Z Fold4 Insta360 X3 Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2022 Hosting door True

Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee