来自大型CSV文件的热图

时间:2016-07-11 09:37:13

标签: python csv matplotlib plot heatmap

我正在尝试从大型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之间,我需要生成和图像,其中0值是冷蓝色像素,1000个值是热红色值,在其他值中降级了,我尝试了一些python实用程序但是他们都说fata太大了,有人有一个库可以绘制大量的数据吗?

我正在使用代码来减去数据:

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;

提前致谢。

修改:Example CSV

2 个答案:

答案 0 :(得分: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

因此它在35秒内制作了200MB的tif文件。内存使用峰值约为30MB RAM,但它也会使用临时文件。

您不能提供您的平台,但您可以使用brew install vips在OS X上安装,或者通过软件包管理器在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])

答案 1 :(得分: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并允许使用Image.fromarray()
  • 轻松地将结果传递给PIL
  • 使用多处理:使用工作池,您可以将要处理的行发送到不同的线程