Skip to content

Instantly share code, notes, and snippets.

@pigreco
Last active April 23, 2023 09:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pigreco/d90304622c6041079a027baef397213b to your computer and use it in GitHub Desktop.
Save pigreco/d90304622c6041079a027baef397213b to your computer and use it in GitHub Desktop.

Estrarre un sottoinsieme di dati da un file csv da 24 mln di righe

Il mio laptop è del 2015, CPU ~i5 8 GB RAM SSD

  • BBOX Calabria

Utility awk da riga di comando

tr -d '"' <population_ita_2019.csv | awk -F, 'NR == 1 || ( 15.6 <= $2 && $2 <= 17.25 && 37.9 <= $1 && $1 <= 40.15 && $3 != 0 )' >output_awk.csv

tempo: 1m7s

Utility XSV da riga di comando

xsv search -s Lat '37\.9|3[8-9]\.|40\.0+|40\.1[0-4]|40\.150*$' population_ita_2019-07-01.csv | xsv search -s Lon '15\.[6-9]|16\.|17\.[0-1]|17\.2[0-4]|17\.250*$' | xsv search -s Population '[^0.0]' >output_xsv.csv

tempo: 13s

Libreria GDAL/OGR da riga di comando

ogr2ogr -f "CSV" output_ogr.csv virtual.vrt -sql "SELECT "Lat", "Lon", "Population" FROM "population_ita_2019" where Lon >= 15.6 AND Lon <= 17.25 AND Lat >= 37.9 AND Lat <= 40.15 AND Population > 0.0"

tempo: 4m14s

Utility Miller da riga di comando

mlr --csv filter '($Lat >=37.9 && $Lat <=40.15) && ($Lon >=15.6 && $Lon <=17.25) && ($Population>0)' population_ita_2019-07-01.csv >output_mlr.csv

tempo: 2m13s

PS: Con Miller potrei dare direttamente il file *.zip, risparmiando il tempo di unzip

Quadro sinottico

Utility tempo
XSV 13s
awk 1m7s
mlr 2m14s
ogr2ogr 4m14s

Visualizzo con VisiData da riga di comando

@miccoli
Copy link

miccoli commented Apr 23, 2023

Non conoscevo XSV: grazie per l'utilissimo post. Aggiungerò questo strumento alla mia cintura degli attrezzi!

Se posso fare un commento, il motivo per il quale XSV vince a mani basse questo confronto è che usando le regex evita lo step di conversione da stringa a virgola mobile (atof in ANSI C), operazione molto più costosa del confronto tra due numeri, ed anche di una regex semplice. Inoltre il comando XSV è strutturato come una pipeline di tre invocazioni e dunque può essere eseguito da tre processi paralleli, cosa che con le altre utility non avviene.

Comunque quando si tratta di scrivere strumenti efficienti, Rust è sempre una ottima scelta...

Visto che scrivere regex strette può essere difficile/laborioso, un approccio alternativo potrebbe essere dare una prima scrematura larga
(per esempio (3[7-9]|40)\.) e poi usare un filtro numerico con uno degli altri strumenti.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment