从dask.Series列表中有效地创建dask.array

时间:2017-12-26 07:14:06

标签: python numpy dask dask-delayed

从dask.Series列表中创建dask.array的最有效方法是什么? 该系列包含500万个300个元素列表。 它目前分为500个分区。 目前我正在尝试:

pt = [delayed(np.array)(y)
      for y in
      [delayed(list)(x)
       for x in series.to_delayed()]]
da = delayed(dask.array.concatenate)(pt, axis=1)
da = dask.array.from_delayed(da, (vec.size.compute(), 300), dtype=float)

这个想法是将每个分区转换为numpy数组和针脚 那些在一起dask.array。 这段代码将永远运行。 只要有足够的RAM,就可以从这些数据中快速地从这些数据构建一个numpy数组。

2 个答案:

答案 0 :(得分:1)

我认为你使用dask.delayed走在正确的轨道上。但是,在系列中调用list可能并不理想。我会创建一个函数,将你的一个系列转换成一个numpy数组,然后用它来延迟。

def convert_series_to_array(pandas_series):  # make this as fast as you can
    ...
    return numpy_array

L = dask_series.to_delayed()
L = [delayed(convert_series_to_array)(x) for x in L]
arrays = [da.from_delayed(x, shape=(np.nan, 300), dtype=...) for x in L]
x = da.concatenate(arrays, axis=0)

另外,关于这一行:

da = delayed(dask.array.concatenate)(pt, axis=1)

你永远不应该在dask函数上调用延迟。他们已经懒惰了。

答案 1 :(得分:0)

看一些虚假数据。以@MRocklin的答案为基础(并在我的特定用例之后进行更多成型),假设您的向量实际上是int列表,而不是float列表,并且该列表存储为字符串。我们将系列进行转换,并将其存储在一个奇怪的数组文件中。

# create dummy data
vectors = [ np.random.randint(low=0,high=100,size=300).tolist() for _ in range(1000) ]
df = pd.DataFrame()
df['vector'] = vectors
df['vector'] = df['vector'].map(lambda x:f"{x}")
df['foo'] = 'bar'
ddf = dd.from_pandas( df, npartitions=100 )

# transform series data to numpy array
def convert_series_to_array( series ):  # make this as fast as you can
    series_ = [ast.literal_eval( i ) for i in series]
    return np.stack(series_, axis=0)

L = ddf['vector'].to_delayed()
L = [delayed(convert_series_to_array)(x) for x in L]
arrays = [da.from_delayed(x, shape=(np.nan, 300), dtype=np.int64) for x in L]
x = da.concatenate(arrays, axis=0)

# store result into a zarr array
x.compute_chunk_sizes().to_zarr( 'toy_dataset.zarr', '/home/user/Documents/', overwrite=True )