0
votes

Optimisation des opérations de concaténate numpy pour de très grands ensembles de données

J'ai un dictionnaire, avec un très grand nombre de clés ( ~ 300k et de croissance) et comme des valeurs qu'il a également un grand nombre d'articles ( ~ 20k ). xxx

Ce que je veux réaliser est de créer deux tableaux: xxx

qui représente essentiellement une cartographie de chaque élément dans chaque élément Définissez avec sa clé correspondante.

J'ai essayé d'utiliser numpy pour ce travail, mais cela prend toujours très longtemps et je veux savoir s'il peut être optimisé.

code numpy: xxx

La deuxième partie est une tentative d'essayer de réduire l'empreinte mémoire de ces variables pour tenir compte de leurs types de données respectifs. Mais je sais qu'ils vont toujours par défaut à 64 bits de variables dans les deux premières opérations (avant d'appliquer le changement de DTYPE), la mémoire sera donc allouée et je risquerai de sortir de la RAM.


0 commentaires

3 Réponses :


0
votes

Il est probablement préférable d'utiliser np.fromiter code> ici. C'est certainement plus facile sur la mémoire car elle évite de créer tous ces temporaires.

horaires: p>

Entrez l'image Description ici P>

import numpy as np
import itertools as it
from simple_benchmark import BenchmarkBuilder

B = BenchmarkBuilder()

@B.add_function()
def pp(a):
    szs = np.fromiter(map(len,a.values()),int,len(a))
    ks = np.fromiter(a.keys(),np.uint32,len(a)).repeat(szs)
    vls = np.fromiter(it.chain.from_iterable(a.values()),np.uint16,ks.size)
    return ks,vls

@B.add_function()
def OP(a):
    keys = np.concatenate(list(map(lambda x: np.repeat(x[0], len(x[1])), a.items())))
    items = np.concatenate(list(map(list, a.values())))
    return keys, items

@B.add_function()
def DevKhadka(a):
    keys = np.array(list(a.keys()), dtype=np.uint32).repeat([len(s) for s in a.values()])
    values = np.concatenate([np.array(list(s), np.uint16) for s in a.values()])
    return keys,values

@B.add_function()
def hpaulj(a):
    ks = list(it.chain.from_iterable([[item[0]]*len(item[1]) for item in a.items()]))                                           
    vls = list(it.chain.from_iterable(a.values()))
    return ks,vls


@B.add_arguments('total no items')
def argument_provider():
    for exp in range(1,12):
        sz = 2**exp
        a = {j:set(np.random.randint(1,2**16,np.random.randint(1,sz)).tolist())
     for j in range(1,10*sz)}
        yield sum(map(len,a.values())),a

r = B.run()
r.plot()

import pylab
pylab.savefig('dct2np.png')


0 commentaires

0
votes

Pour ce petit échantillon, une version de liste pure est considérablement plus rapide que celle numpie: xxx

et xxx paul Panzer's Version: xxx


0 commentaires

0
votes

Je ne sais pas si cela fonctionnera beaucoup mieux mais simple de le faire, c'est comme ça

import numpy as np

keys = np.array(list(dictionary.keys()), dtype=np.uint32).repeat([len(s) for s in dictionary.values()])

values = np.concatenate([np.array(list(s), np.uint16) for s in dictionary.values()])

display(keys)
display(values)


0 commentaires