我正在尝试从大型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
答案 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")
显然,对于非常大的数据集,这不会有效。这有一些可能性:
Image.fromarray()