J'ai un problème (avec ma RAM) ici: il ne peut pas contenir les données que je veux tracer. J'ai suffisamment d'espace HD. Existe-t-il une solution pour éviter cette "observation" de mon ensemble de données?
Concrètement, je m'occupe du traitement numérique du signal et je dois utiliser un taux d'échantillonnage élevé. Mon framework (GNU Radio) enregistre les valeurs (pour éviter d'utiliser trop d'espace disque) en binaire. Je le déballe. Ensuite, j'ai besoin de comploter. J'ai besoin de l'intrigue zoomable et interactive. Et c'est un problème.
Y a-t-il un potentiel d'optimisation à cela, ou un autre langage de programmation/logiciel (comme R ou plus) qui peut gérer de plus grands ensembles de données? En fait, je veux beaucoup plus de données dans mes parcelles. Mais je n'ai aucune expérience avec d'autres logiciels. GNUplot échoue, avec une approche similaire à la suivante. Je ne connais pas R (jet).
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import struct
"""
plots a cfile
cfile - IEEE single-precision (4-byte) floats, IQ pairs, binary
txt - index,in-phase,quadrature in plaintext
note: directly plotting with numpy results into shadowed functions
"""
# unpacking the cfile dataset
def unpack_set(input_filename, output_filename):
index = 0 # index of the samples
output_filename = open(output_filename, 'wb')
with open(input_filename, "rb") as f:
byte = f.read(4) # read 1. column of the vector
while byte != "":
# stored Bit Values
floati = struct.unpack('f', byte) # write value of 1. column to a variable
byte = f.read(4) # read 2. column of the vector
floatq = struct.unpack('f', byte) # write value of 2. column to a variable
byte = f.read(4) # next row of the vector and read 1. column
# delimeter format for matplotlib
lines = ["%d," % index, format(floati), ",", format(floatq), "\n"]
output_filename.writelines(lines)
index = index + 1
output_filename.close
return output_filename.name
# reformats output (precision configuration here)
def format(value):
return "%.8f" % value
# start
def main():
# specify path
unpacked_file = unpack_set("test01.cfile", "test01.txt")
# pass file reference to matplotlib
fname = str(unpacked_file)
plt.plotfile(fname, cols=(0,1)) # index vs. in-phase
# optional
# plt.axes([0, 0.5, 0, 100000]) # for 100k samples
plt.grid(True)
plt.title("Signal-Diagram")
plt.xlabel("Sample")
plt.ylabel("In-Phase")
plt.show();
if __== "__main__":
main()
Quelque chose comme plt.swap_on_disk () pourrait mettre en cache les trucs sur mon SSD;)
Vos données ne sont donc pas si grandes, et le fait que vous ayez du mal à les tracer indique des problèmes avec les outils. Matplotlib .... n'est pas si bon. Il a beaucoup d'options et la sortie est bonne, mais c'est un énorme porc de mémoire et il suppose fondamentalement que vos données sont petites. Mais il existe d'autres options.
Ainsi, à titre d'exemple, j'ai généré un fichier de points de données de 20 millions de données 'bigdata.bin' en utilisant ce qui suit:
#!/usr/bin/env python
import numpy
import scipy.io.numpyio
npts=20000000
filename='bigdata.bin'
def main():
data = (numpy.random.uniform(0,1,(npts,3))).astype(numpy.float32)
data[:,2] = 0.1*data[:,2]+numpy.exp(-((data[:,1]-0.5)**2.)/(0.25**2))
fd = open(filename,'wb')
scipy.io.numpyio.fwrite(fd,data.size,data)
fd.close()
if __== "__main__":
main()
Cela génère un fichier de taille ~ 229 Mo, ce qui n'est pas si gros; mais vous avez dit que vous aimeriez aller dans des fichiers encore plus gros, donc vous atteindrez éventuellement les limites de mémoire.
Concentrons-nous d'abord sur les tracés non interactifs. La première chose à réaliser est que les tracés vectoriels avec des glyphes à chaque point vont être un désastre - pour chacun des 20 M points, dont la plupart vont se chevaucher de toute façon, essayant de rendre de petites croix ou cercles ou quelque chose va être un diaster, générer des fichiers énormes et prendre des tonnes de temps. C'est, je pense, ce qui coule par défaut matplotlib.
Gnuplot n'a aucun mal à gérer cela:
gnuplot> set term png
gnuplot> set output 'foo.png'
gnuplot> plot 'bigdata.bin' binary format="%3float32" using 2:3 with dots
Et même Matplotlib peut être amené à se comporter avec une certaine prudence (en choisissant un back-end raster et en utilisant des pixels pour marquer des points):
#!/usr/bin/env python
import numpy
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
datatype=[('index',numpy.float32), ('floati',numpy.float32),
('floatq',numpy.float32)]
filename='bigdata.bin'
def main():
data = numpy.memmap(filename, datatype, 'r')
plt.plot(data['floati'],data['floatq'],'r,')
plt.grid(True)
plt.title("Signal-Diagram")
plt.xlabel("Sample")
plt.ylabel("In-Phase")
plt.savefig('foo2.png')
if __== "__main__":
main()
Maintenant, si vous voulez interactif, vous allez devoir regrouper les données à tracer et zoomer à la volée. Je ne connais pas d'outils python qui vous aideront à faire cela à la légère.
D'un autre côté, le traçage des données volumineuses est une tâche assez courante, et il existe des outils prêts à l'emploi. Paraview est mon préféré, et VisIt en est un autre. Ils sont tous deux principalement destinés aux données 3D, mais Paraview en particulier fait également 2d, et est très interactif (et a même une interface de script Python). La seule astuce sera d'écrire les données dans un format de fichier que Paraview peut facilement lire.
Vous pouvez certainement optimiser la lecture de votre fichier: vous pouvez le lire directement dans un tableau NumPy, afin de tirer parti de la vitesse brute de NumPy. Vous avez quelques options. Si RAM est un problème, vous pouvez utiliser memmap , qui conserve la plupart du fichier sur le disque (au lieu de la RAM):
# Each data point is a sequence of three 32-bit floats:
data = np.memmap(filename, mode='r', dtype=[('index', 'float32'), ('floati','float32'), ('floatq', 'float32')])
Si RAM n'est pas un problème, vous pouvez mettre tout le tableau dans RAM avec fromfile :
data = np.fromfile(filename, dtype=[('index', 'float32'), ('floati','float32'), ('floatq', 'float32')])
Le traçage peut alors être effectué avec la fonction habituelle plot(*data)
de Matplotlib, éventuellement par la méthode de "zoom avant" proposée dans une autre solution.
Un projet plus récent a un fort potentiel pour les grands ensembles de données: Bokeh , qui a été créé avec exactement cela à l'esprit .
En fait, seules les données pertinentes à l'échelle du tracé sont envoyées au backend d'affichage. Cette approche est beaucoup plus rapide que l'approche Matplotlib.
Une enquête sur un logiciel de traçage interactif open source avec un benchmark de 10 millions de points de dispersion sur Ubuntu
Inspiré du cas d'utilisation décrit à: https://stats.stackexchange.com/questions/376361/how-to-find-the-sample-points-that-have-statistically-meaningful-large-outlier- r J'ai comparé quelques implémentations avec les données linéaires de 10 millions de points très simples et naïves suivantes:
i=0;
while [ "$i" -lt 10000000 ]; do
echo "$i,$((2 * i)),$((4 * i))"; i=$((i + 1));
done > 10m.csv
Les premières lignes de 10m.csv
Ressemblent à ceci:
0,0,0
1,2,4
2,4,8
3,6,12
4,8,16
Fondamentalement, je voulais:
Pour m'amuser encore plus, j'ai également préparé un ensemble de données d'un milliard de points encore plus grand au cas où l'un des programmes pourrait gérer les 10 millions de points! Les fichiers CSV devenaient un peu chancelants, je suis passé à HDF5:
import h5py
import numpy
size = 1000000000
with h5py.File('1b.hdf5', 'w') as f:
x = numpy.arange(size + 1)
x[size] = size / 2
f.create_dataset('x', data=x, dtype='int64')
y = numpy.arange(size + 1) * 2
y[size] = 3 * size / 2
f.create_dataset('y', data=y, dtype='int64')
z = numpy.arange(size + 1) * 4
z[size] = -1
f.create_dataset('z', data=z, dtype='int64')
Cela produit un fichier ~ 23GiB contenant une ligne droite comme 10m.csv
Et une valeur aberrante en haut au centre du graphique.
Les tests ont été effectués dans Ubuntu 18.10 sauf indication contraire dans la sous-section, dans un ordinateur portable ThinkPad P51 avec processeur Intel Core i7-7820HQ (4 cœurs/8 threads), 2x Samsung M471A2K43BB1-CRC RAM = (2 x 16 Go), GPU NVIDIA Quadro M1200 4 Go GDDR5.
Résumé des résultats
C'est ce que j'ai observé, compte tenu de mon cas d'utilisation de test très spécifique et du fait que je suis un premier utilisateur de nombreux logiciels examinés:
Gère-t-il 10 millions de points:
Vaex Yes, tested up to 1 Billion!
VisIt Yes, but not 100m
Paraview Barely
Mayavi Yes
gnuplot Barely on non-interactive mode.
matplotlib No
Bokeh No, up to 1m
At-il beaucoup de fonctionnalités:
Vaex Yes.
VisIt Yes, 2D and 3D, focus on interactive.
Paraview Same as above, a bit less 2D features maybe.
Mayavi 3D only, good interactive and scripting support, but more limited features.
gnuplot Lots of features, but limited in interactive mode.
matplotlib Same as above.
Bokeh Yes, easy to script.
L'interface graphique se sent-elle bien (sans considérer de bonnes performances):
Vaex Yes, Jupyter widget
VisIt No
Paraview Very
Mayavi OK
gnuplot OK
matplotlib OK
Bokeh Very, Jupyter widget
Vaex 2.0.2
https://github.com/vaexio/vaex
Installez et faites fonctionner un monde bonjour comme indiqué dans: Comment faire une sélection interactive de zoom/point de nuage de points en Vaex?
J'ai testé le vaex avec jusqu'à 1 milliard de points et ça a marché, c'est génial!
C'est "Python-scripted-first" qui est excellent pour la reproductibilité, et me permet d'interfacer facilement avec d'autres choses Python.
La configuration de Jupyter a quelques parties mobiles, mais une fois que je l'ai fait fonctionner avec virtualenv, c'était incroyable.
Pour charger notre exécution CSV dans Jupyter:
import vaex
df = vaex.from_csv('10m.csv', names=['x', 'y', 'z'],)
df.plot_widget(df.x, df.y, backend='bqplot')
et nous pouvons voir instantanément:
Maintenant, nous pouvons zoomer, faire un panoramique et sélectionner des points avec la souris, et les mises à jour sont vraiment rapides. Ici, j'ai zoomé pour voir certains points individuels et en ai sélectionné quelques-uns (un léger rectangle plus léger sur l'image):
Une fois la sélection effectuée avec la souris, cela a exactement le même effet que l'utilisation de la méthode df.select()
. Nous pouvons donc extraire les points sélectionnés en exécutant dans Jupyter:
df.to_pandas_df(selection=True)
qui produit des données au format:
x y z index
0 4525460 9050920 18101840 4525460
1 4525461 9050922 18101844 4525461
2 4525462 9050924 18101848 4525462
3 4525463 9050926 18101852 4525463
4 4525464 9050928 18101856 4525464
5 4525465 9050930 18101860 4525465
6 4525466 9050932 18101864 4525466
Puisque 10M points fonctionnaient bien, j'ai décidé d'essayer 1B points!
import vaex
df = vaex.open('1b.hdf5')
df.plot_widget(df.x, df.y, backend='bqplot')
Pour observer la valeur aberrante, qui était invisible sur le tracé d'origine, nous pouvons suivre Comment changer le style de point dans un vaex interactif Jupyter bqplot plot_widget pour rendre les points individuels plus grands et visibles? et utiliser:
df.plot_widget(df.x, df.y, f='log', shape=128, backend='bqplot')
qui produit:
et après avoir sélectionné le point:
nous obtenons les données complètes de la valeur aberrante:
x y z
0 500000000 1500000000 -1
Existe-t-il un moyen de rendre ces points individuels plus visibles? Demandé à: Comment changer le style de point dans un vaex interactif Jupyter bqplot plot_widget pour rendre les points individuels plus grands et visibles?
Résultat: ça marche !!!! Le chargement initial prend environ 10 secondes, les zooms et la sélection de la souris environ 3 secondes chacun, et l'évaluation finale de la sélection également environ 10 secondes! Toutes les vitesses impressionnantes pour un ensemble de données aussi massif.
Voici une démo des créateurs avec un jeu de données plus intéressant et plus de fonctionnalités: https://www.youtube.com/watch?v=2Tt0i823-ec&t=77
Testé dans Ubuntu 19.04.
VisIt 2.13.3
Site Web: https://wci.llnl.gov/simulation/computer-codes/visit
Licence: BSD
Développé par Lawrence Livermore National Laboratory , qui est un laboratoire National Nuclear Security Administration , vous pouvez donc imaginer que des points de 10 m ne seront rien si je pouvais le faire fonctionner.
Installation: il n'y a pas de paquet Debian, il suffit de télécharger les binaires Linux depuis le site Web. Fonctionne sans installation. Voir aussi: https://askubuntu.com/questions/966901/installing-visit
Basé sur VTK qui est la bibliothèque backend que la plupart des logiciels de graphisme haute performance utilisent. Écrit en C.
Après 3 heures de jeu avec l'interface utilisateur, je l'ai fait fonctionner et cela a résolu mon cas d'utilisation comme détaillé sur: https://stats.stackexchange.com/questions/376361/how-to-find- the-sample-points-that-have-statistically-significant-large-outlier-r
Voici à quoi cela ressemble sur les données de test de ce post:
et un zoom avec quelques choix:
et voici la fenêtre des choix:
En termes de performances, VisIt était très bon: chaque opération graphique ne prenait que peu de temps ou était immédiate, et je pense qu'elle peut facilement gérer beaucoup plus de données. Quand j'ai dû attendre, il affiche un message de "traitement" avec le pourcentage de travail restant, et l'interface graphique ne s'est pas figée.
Étant donné que 10 millions de points fonctionnaient si bien, j'ai également essayé 100 millions de points (un fichier CSV 2,7 G), mais il s'est écrasé/est entré dans un état étrange, malheureusement, je l'ai regardé dans htop
alors que les 4 threads VisIt occupaient tous mes 16GiB RAM et est décédé probablement en raison d'une panne de malloc.
Le démarrage initial a été un peu douloureux:
J'attribue ces problèmes à:
J'aime aussi la façon dont un peu d'infrastructure LLNL s'infiltre dans ce dépôt. Voir par exemple docs/OfficeHours.txt et d'autres fichiers dans ce répertoire! Je suis désolé pour Brad qui est le "gars du lundi matin"! Oh, et le mot de passe du répondeur est "Kill Ed", n'oubliez pas cela.
Paraview 5.4.1
Site Web: https://www.paraview.org/
Licence: BSD
Installation:
Sudo apt-get install paraview
Développé par Sandia National Laboratories qui est un autre laboratoire de la NNSA, nous nous attendons donc à nouveau à ce qu'il gère facilement les données. Également basé sur VTK et écrit en C++, ce qui était encore plus prometteur.
Cependant, j'ai été déçu: pour une raison quelconque, 10 millions de points ont rendu l'interface graphique très lente et ne répond pas.
Je vais bien avec un moment contrôlé et bien annoncé "Je travaille maintenant, attendez un peu", mais l'interface graphique se bloque pendant que cela se produit? Pas acceptable.
htop a montré que Paraview utilisait 4 threads, mais ni le CPU ni la mémoire n'étaient au maximum.
Côté GUI, Paraview est très agréable et moderne, bien meilleur que VisIt quand il ne bégaie pas. Le voici avec un nombre de points inférieur pour référence:
et voici la feuille de calcul avec une sélection manuelle de points:
Un autre inconvénient est que Paraview ressentait un manque de fonctionnalités par rapport à VisIt, par exemple:
Mayavi 4.6.2
Site Web: https://github.com/enthought/mayavi
Développé par: Enthought
Installer:
Sudo apt-get install libvtk6-dev
python3 -m pip install -u mayavi PyQt5
Le VTK Python one.
Mayavi semble être très concentré sur la 3D, je n'ai pas trouvé comment y faire des tracés 2D, donc il ne le coupe malheureusement pas pour mon cas d'utilisation.
Pour vérifier les performances cependant, j'ai adapté l'exemple de: https://docs.enthought.com/mayavi/mayavi/auto/example_scatter_plot.html pour 10 millions de points, et il fonctionne très bien sans retard :
import numpy as np
from tvtk.api import tvtk
from mayavi.scripts import mayavi2
n = 10000000
pd = tvtk.PolyData()
pd.points = np.linspace((1,1,1),(n,n,n),n)
pd.verts = np.arange(n).reshape((-1, 1))
pd.point_data.scalars = np.arange(n)
@mayavi2.standalone
def main():
from mayavi.sources.vtk_data_source import VTKDataSource
from mayavi.modules.outline import Outline
from mayavi.modules.surface import Surface
mayavi.new_scene()
d = VTKDataSource()
d.data = pd
mayavi.add_source(d)
mayavi.add_module(Outline())
s = Surface()
mayavi.add_module(s)
s.actor.property.trait_set(representation='p', point_size=1)
main()
Sortie:
Je n'ai cependant pas pu zoomer suffisamment pour voir des points individuels, le plan 3D proche était trop loin. Peut-être qu'il y a un moyen?
Une chose intéressante à propos de Mayavi est que les développeurs ont mis beaucoup d'efforts pour vous permettre de lancer et de configurer l'interface graphique à partir d'un script Python bien, tout comme Matplotlib et gnuplot. Il semble que cela soit également possible à Paraview, mais les documents ne sont pas aussi bons au moins.
En général, il ne semble pas être une fonctionnalité complète comme VisIt/Paraview. Par exemple, je n'ai pas pu charger directement un CSV depuis l'interface graphique: Comment charger un fichier CSV depuis l'interface graphique Mayavi?
Gnuplot 5.2.2
Site Web: http://www.gnuplot.info/
gnuplot est vraiment pratique quand j'ai besoin d'aller vite et sale, et c'est toujours la première chose que j'essaye.
Installation:
Sudo apt-get install gnuplot
Pour une utilisation non interactive, il peut gérer 10 m de points raisonnablement bien:
#!/usr/bin/env gnuplot
set terminal png size 1024,1024
set output "gnuplot.png"
set key off
set datafile separator ","
plot "10m1.csv" using 1:2:3:3 with labels point
qui s'est terminé en 7 secondes:
Mais si j'essaie de devenir interactif avec
#!/usr/bin/env gnuplot
set terminal wxt size 1024,1024
set key off
set datafile separator ","
plot "10m.csv" using 1:2:3 palette
et:
gnuplot -persist main.gnuplot
le rendu initial et les zooms semblent alors trop lents. Je ne vois même pas la ligne de sélection du rectangle!
Notez également que pour mon cas d'utilisation, j'avais besoin d'utiliser des étiquettes hypertextes comme dans:
plot "10m.csv" using 1:2:3 with labels hypertext
mais il y avait un bug de performance avec la fonctionnalité d'étiquettes, y compris pour le rendu non interactif. Mais je l'ai signalé et Ethan l'a résolu en une journée: https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/qpL8aJIi9ZE
Je dois cependant dire qu'il existe une solution de contournement raisonnable pour la sélection des valeurs aberrantes: ajoutez simplement des étiquettes avec l'ID de ligne à tous les points! S'il y a beaucoup de points à proximité, vous ne pourrez pas lire les étiquettes. Mais pour les valeurs aberrantes dont vous vous souciez, vous pourriez le faire! Par exemple, si j'ajoute une valeur aberrante à nos données d'origine:
cp 10m.csv 10m1.csv
printf '2500000,10000000,40000000\n' >> 10m1.csv
et modifiez la commande plot pour:
#!/usr/bin/env gnuplot
set terminal png size 1024,1024
set output "gnuplot.png"
set key off
set datafile separator ","
plot "10.csv" using 1:2:3:3 palette with labels
Cela a considérablement ralenti le tracé (40 minutes après le correctif mentionné ci-dessus), mais produit une sortie raisonnable:
donc avec un peu de filtrage des données, on y arriverait finalement.
Matplotlib 1.5.1, numpy 1.11.1, Python 3.6.7
Site Web: https://matplotlib.org/
Matplotlib est ce que j'essaie habituellement lorsque mon script gnuplot commence à devenir trop fou.
numpy.loadtxt
Seul a pris environ 10 secondes, donc je savais que ça n'allait pas bien se passer:
#!/usr/bin/env python3
import numpy
import matplotlib.pyplot as plt
x, y, z = numpy.loadtxt('10m.csv', delimiter=',', unpack=True)
plt.figure(figsize=(8, 8), dpi=128)
plt.scatter(x, y, c=z)
# Non-interactive.
#plt.savefig('matplotlib.png')
# Interactive.
plt.show()
D'abord, la tentative non interactive a donné une bonne sortie, mais a pris 3 minutes et 55 secondes ...
L'interactif a ensuite mis beaucoup de temps sur le rendu initial et sur les zooms. Non utilisable:
Notez sur cette capture d'écran comment la sélection de zoom, qui devrait immédiatement zoomer et disparaître, est restée longtemps à l'écran pendant qu'elle attendait que le zoom soit calculé!
J'ai dû commenter plt.figure(figsize=(8, 8), dpi=128)
pour que la version interactive fonctionne pour une raison quelconque, sinon elle a explosé avec:
RuntimeError: In set_size: Could not set the fontsize
Bokeh 1.3.1
https://github.com/bokeh/bokeh
Installation d'Ubuntu 19.04:
python3 -m pip install bokeh
Lancez ensuite Jupyter:
jupyter notebook
Maintenant, si je trace des points de 1 m, tout fonctionne parfaitement, l'interface est impressionnante et rapide, y compris le zoom et les informations de survol:
from bokeh.io import output_notebook, show
from bokeh.models import HoverTool
from bokeh.transform import linear_cmap
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
import numpy as np
N = 1000000
source = ColumnDataSource(data=dict(
x=np.random.random(size=N) * N,
y=np.random.random(size=N) * N,
z=np.random.random(size=N)
))
hover = HoverTool(tooltips=[("z", "@z")])
p = figure()
p.add_tools(hover)
p.circle(
'x',
'y',
source=source,
color=linear_cmap('z', 'Viridis256', 0, 1.0),
size=5
)
show(p)
Vue initiale:
Après un zoom:
Si je monte jusqu'à 10m bien qu'il s'étouffe, htop
montre que le chrome a 8 threads occupant toute ma mémoire dans un état ininterruptible IO.
Cela demande de référencer les points: Comment référencer les points de données bokeh sélectionnés
PyViz https://pyviz.org/
TODO évaluer.
Intègre Bokeh + datahader + autres outils.
Démonstration vidéo des points de données 1B: https://www.youtube.com/watch?v=k27MJJLJNT4 "PyViz: Tableaux de bord pour visualiser 1 milliard de points de données dans 30 lignes de Python" par "Anaconda, Inc." publié le 2018-04-17.
Je suggérerais quelque chose d'un peu complexe, mais cela devrait fonctionner: créez votre graphique à différentes résolutions, pour différentes plages.
Pensez à Google Earth, par exemple. Si vous dézoomez au niveau maximum pour couvrir toute la planète, la résolution est la plus basse. Lorsque vous zoomez, les images changent pour des photos plus détaillées, mais uniquement sur la région sur laquelle vous zoomez.
Donc, fondamentalement pour votre tracé (est-ce 2D? 3D? Je suppose que c'est 2D), je vous suggère de construire un grand graphique qui couvre toute la plage [0, n] avec une faible résolution, 2 graphiques plus petits qui couvrent [0, n/2] et [n/2 + 1, n] avec deux fois la résolution du grand, 4 graphiques plus petits couvrant [0, n/4] ... [3 * n/4 + 1, n] avec deux fois la résolution des 2 ci-dessus, et ainsi de suite.
Je ne suis pas sûr que mon explication soit vraiment claire. De plus, je ne sais pas si ce type de graphique multi-résolution est géré par un programme de tracé existant.
Je me demande s'il y a une victoire à gagner en accélérant la recherche de vos points? (J'ai été intrigué par les arbres R * (r star) pendant un certain temps.)
Je me demande si l'utilisation de quelque chose comme un arbre r * dans ce cas pourrait être la voie à suivre. (lors d'un zoom arrière, des nœuds plus élevés dans l'arbre peuvent contenir des informations sur le rendu plus grossier et zoomé, les nœuds plus loin vers les feuilles contiennent les échantillons individuels)
peut-être même la mémoire mappe l'arborescence (ou la structure que vous finissez par utiliser) dans la mémoire pour maintenir vos performances et votre RAM utilisation faible. (vous déchargez la tâche de gestion de la mémoire sur le noyau)
espérons que cela a du sens .. divaguer un peu. il est tard!