Python Datashader用于绘制大型2D点阵列

时间:2017-01-06 10:41:59

标签: python bokeh dask datashader

我正在寻找一些帮助/建议使用数据共享器将大型2D数据阵列绘制为一系列点,按振幅着色。 我处理的数据存储在几个2D HDF5数据集中,时间索引存储在单独的数据集中。数据的第二维是空间维度(以m为单位的距离),它是浮动的非均匀阶梯系列。 数据集通常非常大(~1000 x> 1000000),所以我想dask来处理核心外数据帧的构造,其中数据的y位置存储为列标题, x-location是帧索引,我想将点颜色映射到数据值 当我想在数据共享器中从dask数据框中绘制这个问题时,我遇到了这个问题,目前,我发现的唯一方法是展平数据帧并创建两个相应的' x'并且' y'用于存放索引和y位置的列。 任何人都可以帮助我理解这种绘图是否可以在没有压扁数据的步骤的情况下进行?

这是我迄今所做的一个例子:

import datashader as ds
import datashader.transfer_functions as tf
import numpy as np
import pandas as pd
import dask.dataframe as dd
import dask.array as da

import bokeh.plotting as bk
from bokeh.palettes import viridis

from datashader.bokeh_ext import InteractiveImage

bk.output_notebook()

# ------------------------
# This is a proxy for a function, which creates a delayed frame from
# a series of delayed pandas dataframes, each reading from a separate 
# h5 dataset.
random_data = da.random.random((10000, 1000), chunks = (1000, 100))
frame = dd.from_array(random_data)
# ------------------------

# ------------------------
# Flatten the dataframe and create two additional arrays holding the x and y
# locations.
a = frame.compute() # I want to avoid this call on the whole dataframe
index = [a.index] * len(a.columns)
index = np.vstack(index).reshape((-1), order = 'F')
columns = [a.columns] * len(a.index)
columns = [item for sublist in columns for item in sublist]
data = a.values.flatten()

# ------------------------
# Now creating an in-memory frame for the data
plot_frame = pd.DataFrame(columns = ['x', 'y', 'z']) # Empty frame
plot_frame.x = index
plot_frame.y = columns[::-1] #Reverse column order to plot
plot_frame.z = data
# ------------------------

x_range = [a.index[0], a.index[-1]]
y_range = [a.columns[0], a.columns[-1]]

def create_image(x_range = x_range, y_range = y_range[::-1], w=500, h=500):
    cvs = ds.Canvas(x_range=x_range, y_range=y_range, plot_height=h, plot_width=w)
    agg = cvs.points(plot_frame, 'x', 'y', ds.mean('z'))
    return tf.shade(agg, cmap = viridis(256))

def base_plot(tools='pan,wheel_zoom,reset, box_zoom, save'):
    p = bk.figure(x_range = x_range, y_range = y_range, tools=tools, 
                  plot_width=900, plot_height=500, outline_line_color=None,
        min_border=0, min_border_left=0, min_border_right=0,
        min_border_top=0, min_border_bottom=0, x_axis_type = 'datetime')   
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None
    return p

p = base_plot()
InteractiveImage(p, create_image)

有人能推荐一种通过数据共享管道更有效地处理这个问题的方法吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

我的回复只是为了让您知道数据分析维护者已经看到您的问题,但遗憾的是我不知道如何正确地完成您的要求。正如你在OSM example in datashader中看到的那样,核心数据集已经很好地使用了dask + datashader,但在这种情况下,数据首先被放入一个合适的块和列可寻址格式(castra最初,但现在我和#39; d亲自推荐基于benchmarking的fastparquet。在这里,您似乎试图保留磁盘上的原始组织,同时使其看起来像一个扁平的数据帧,我不知道如何实现。您可以考虑直接询问dask维护者;它绝对不是数据共享团队目前正在调查的事情。