2016-07-11 10 views
1

Ich versuche, eine Heatmap aus einer großen CSV-Datei zu erstellen. Genauer gesagt habe ich eine Matrix wie folgt aus:Heatmap aus einer großen CSV-Datei

O0 X1 X2 X3 . . . Xn 
Y1 Z1 Z2 Z3 . . . Zn 
Y2 Z1 Z2 Z3 . . . Zn 
Y3 Z1 Z2 Z3 . . . Zn 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
Yn Z1 Z2 Z3 . . . Zn 

Mit mehr als 4K X-Werte und 15K Y-Werte, sind die Z-Werte zwischen 0 a 1000 und ich brauche zu erzeugen, und die Bild wo 0 Werte sind ein kaltes Blau Pixel und 1000 Werte sind ein Heat-Red-Wert, mit einem Rest in den Werten, versuchte ich mit einigen Python-Utilities, aber alle von ihnen sagen, dass die Fata zu groß ist, jemand eine Bibliothek haben, um diese riesige Menge an Daten zu plotten?

Es ist der Code Ich verwende die Daten zu subtrahieren:

reader = csv.reader(open('../Data/160627_185815_1_OK.csv', 'rt'), delimiter=';') 
reader2 = csv.reader(open('../Data/160627_195553_1_OK.csv', 'rt'), delimiter=';') 
first = True 
valuesGT1 = 0 
print(reader) 
Z = [] 
for row in reader: 
    row2 = next(reader2) 
    row2.pop(0) 
    row.pop(0) 
    if not first: 
     C = [float(a) - float(b) for a, b in zip(row, row2)] 
     with open('results_test.csv', 'a') as csvfile: 
      spamwriter = csv.writer(csvfile, delimiter=',', 
            quotechar='|', quoting=csv.QUOTE_MINIMAL) 
      spamwriter.writerow(C) 
      csvfile.close() 
     Z.append(C) 
    else: 
     first = False; 

Vielen Dank im Voraus.

Edit: Example CSV

+0

Woah, also wirst du ein 4000px x 15000px Bild erzeugen? –

+0

Könnten Sie ein csv als Beispiel angeben (vielleicht nur einen 100 * 100-Auszug), damit wir echte Daten haben, mit denen wir arbeiten können? – Cyrbil

+0

@Cyrbil Hallo, es gibt einen Auszug aus einer Datei: [link] (http://www.sharecsv.com/s/a0e19fb1a1151a95b0cd3dea8f75954a/TESTCSV100x100.csv) Danke. –

Antwort

1

Ich habe Ihr Problem mit vips versucht. Hier ist mein Programm:

#!/usr/bin/python 

import sys 

import gi 
gi.require_version('Vips', '8.0') 
from gi.repository import Vips 

im = Vips.Image.new_from_file(sys.argv[1]) 
im = (255 * im/1000).falsecolour() 
im.write_to_file(sys.argv[2]) 

Ich lief es so auf meinem Laptop gegen einige Testdaten Ich machte:

$ wc x.csv 
    14990 122873030 362045970 x.csv 
$ time ./heatmap.py x.csv x.tif 

real 0m36.415s 
user 0m37.508s 
sys 0m0.904s 
$ ls -l x.tif 
-rw-rw-r-- 1 john john 184333196 Jul 14 10:01 x.tif 
$ vipsheader x.tif 
x.tif: 4099x14990 uchar, 3 bands, srgb, tiffload 

So macht es eine 200MB tif-Datei in etwas mehr als 35 Sekunden. Der Arbeitsspeicherverbrauch liegt bei etwa 30 MB RAM, obwohl auch eine temporäre Datei verwendet wird.

Sie geben Ihre Plattform nicht, aber Sie können unter OS X mit brew install vips oder auf Linux über Ihren Paketmanager installieren. Unter Windows ist es etwas schwieriger.

Bearbeiten: Ich sehe Ihre Datei ist der Unterschied zwischen zwei anderen CSV-Dateien. Du könntest die ganze Sache in vips tun, etwas wie:

a = Vips.Image.new_from_file(sys.argv[1]) 
b = Vips.Image.new_from_file(sys.argv[2]) 
heatmap = (255 * (a - b)/1000).falsecolour() 
heatmap.write_to_file(sys.argv[3]) 
+0

Danke, das macht es einfach. –

0

Das ist, was ich bisher habe:

import csv 
from PIL import Image 

with open('TESTCSV100x100.csv') as f: 
    reader = csv.reader(f, delimiter=';') 

    i, j = 0, 0 
    pixels = dict() 
    for i, row in enumerate(reader): 
     for j, val in enumerate(row): 
      r, g, b = (int(int(val)/(1000/255)), 
         int(20 - int(val)/(1000/20)), 
         int(255 - int(val)/(1000/255))) 
      pixels[i, j] = (r, g, b) 

img = Image.new('RGB', (i + 1, j + 1), "black") 
data = img.load() 
for k, v in pixels.items(): 
    data.__setitem__(k, v) 

img.save('/tmp/test.jpg', "JPEG") 

Offensichtlich für sehr große Daten-Set, das wird nicht effizient sein. Hier besteht eine gewisse Wahrscheinlichkeit:

  • Mit numpy: Es hat eine csv lesen kann sehr schnell und ermöglicht es das Ergebnis PIL leicht zu passieren mit Image.fromarray()
  • Verwendung Multiprozessing: Mit einem Pool von Arbeitnehmern, können Sie Linien senden zu unterschiedlichen Threads verarbeitet werden