J'ai un dictionnaire, avec un très grand nombre de clés ( ~ 300k strong> et de croissance) et comme des valeurs qu'il a également un grand nombre d'articles ( Ce que je veux réaliser est de créer deux tableaux: p> qui représente essentiellement une cartographie de chaque élément dans chaque élément Définissez avec sa clé correspondante. P> J'ai essayé d'utiliser numpy em> pour ce travail, mais cela prend toujours très longtemps et je veux savoir s'il peut être optimisé. p> code numpy: p> 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. p> p>
3 Réponses :
Il est probablement préférable d'utiliser horaires: p> np.fromiter code> ici. C'est certainement plus facile sur la mémoire car elle évite de créer tous ces temporaires.
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')
Pour ce petit échantillon, une version de liste pure est considérablement plus rapide que celle numpie: et p>
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)