2016-07-11 2 views
1

Я пытаюсь построить карту тепла из большого CSV. В частности у меня есть матрица так:Карта с большим CSV-файлом

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 

с более чем 4K X значений, а значения 15K Y, значение Z между 0 1000, и мне нужно генерировать и изображение, где-значения являются холодным синим пиксель и 1000 значений - это тепловое красное значение, с ухудшенными остальными значениями, я пытался использовать некоторые утилиты python, но все они говорят, что фта слишком велика, у кого-то есть библиотека для построения огромного количества данных?

Существует код, я использую для вычитать данные:

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; 

Спасибо заранее.

Edit: Example CSV

+0

Woah, так что вы собираетесь создать изображение размером 4000 пикселей x 15000 пикселей? –

+0

Не могли бы вы предоставить пример csv (может быть, только экстент 100 * 100), чтобы мы могли работать с реальными данными? – Cyrbil

+0

@Cyrbil Привет, есть выдержка из файла: [link] (http://www.sharecsv.com/s/a0e19fb1a1151a95b0cd3dea8f75954a/TESTCSV100x100.csv) Спасибо. –

ответ

1

Я пробовал вашу проблему, используя vips. Вот моя программа:

#!/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]) 

Я побежал, как это на моем ноутбуке против некоторых тестовых данных я сделал:

$ 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 

Так что делает файл TIF 200MB в чуть более 35 секунд. Пики памяти используют около 30 МБ ОЗУ, хотя он также будет использовать временный файл.

Вы не предоставляете свою платформу, но вы можете установить ее на OS X с помощью brew install vips или на linux через диспетчер пакетов. Это немного сложнее в Windows.

Редактировать: Я вижу, что ваш файл является разницей между двумя другими CSV-файлами. Вы могли бы сделать все это в vips, что-то вроде:

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

Спасибо, что облегчают. –

0

Это то, что я до сих пор:

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") 

Очевидно, что для вашего очень большого набора данных, это не будет эффективным. Вот некоторые возможности:

  • Использование NumPy: Он может читать CSV очень быстро, и это позволяет передать результат в PIL легко с Image.fromarray()
  • использования многопроцессорной: С бассейном работников, вы можете отправить линии в обрабатываются на разные темы
Смежные вопросы