将图像加载到Dask Dataframe中

时间:2019-06-16 16:40:52

标签: python pandas dask dask-delayed

我有一个dask数据框,该数据框在一列中包含图像路径(称为img_paths)。下一步,我想使用这些图像路径将图像加载到另一列(称为img_loaded)中,然后应用一些预处理功能。

但是,在加载(或读取图像)过程中,我总是得到不同的结果,包括一次延迟的imread函数包装,另一次正确的图像加载(我可以看到数组)以及其余时间: FileNotFoundError

除了以下示例外,我还使用了map_partitions函数,但是除了没有数组之外,我还得到了类似的输出。最后,我想使用map_partitions函数而不是apply函数。

以下是我的代码和有关问题的说明:

import pandas as pd
import dask
import dask.dataframe as dd
from skimage.io import imread

imgs = ['https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a'] * 42

# create a pandas dataframe using image paths
df = pd.DataFrame({"img_paths": imgs})

# convert it into dask dataframe
ddf = dd.from_pandas(df, npartitions=2)

# convert imread function as delayed
delayed_imread = dask.delayed(imread, pure=True)

第一次尝试:使用lambda函数并将延迟的imread应用于每个单元格

ddf["img_loaded"] = ddf.images.apply(lambda x: delayed_imread(x))
ddf.compute()

使用imread方法时,得到的是延迟compute()函数的包装。我不懂为什么?以下是输出:

enter image description here

第二次尝试:不使用lambda函数

ddf["img_loaded"] = ddf.images.apply(delayed_imread)
ddf.compute()

这有效!至少,我可以将加载的图像视为数组。但是,我真的不明白为什么吗?为什么这与第一个解决方案(即使用lambda函数)不同?输出如下:

enter image description here

第三次尝试:使用/不使用lambda函数且不使用延迟的imread

ddf["load"] = ddf.images.apply(imread) # or, lambda x: imread(x)
ddf.compute()

这里,再次出于实验目的,我没有使用延迟的imread函数,而是仅使用了skimage.io.imread函数。而且,我尝试了同时使用lambda函数和不使用lambda函数。每次,我都会得到 FileNotFoundError 。我没有得到。使用无延迟读取功能时,为什么找不到图像路径(尽管它们是正确的)?

除了罗纳德的答案,如何使用map_partitions函数:

ddf["img_loaded"] = ddf.map_partitions(lambda df: df.images.apply(lambda x: imread(x)), meta=("images", np.uint8)).compute()
ddf.compute()

1 个答案:

答案 0 :(得分:1)

解决方案

form

说明

如果您确实尝试应用import pandas as pd import dask import dask.dataframe as dd import numpy as np from skimage.io import imread imgs = ['https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a'] * 4 # create a pandas dataframe using image paths df = pd.DataFrame({"img_paths": imgs}) # convert it into dask dataframe ddf = dd.from_pandas(df, npartitions=2) # convert imread function as delayed delayed_imread = dask.delayed(imread, pure=True) # give dask information about the function output type ddf['img_paths'].apply(imread, meta=('img_loaded', np.uint8)).compute() # OR turn it into dask.dealayed, which infers output type `object` ddf['img_paths'].apply(delayed_imread).compute() 函数,而没有进行计算,则会看到print代码的原因:FileNotFoundError

ddf.images.apply(imread).compute()

输出:

ddf['img_paths'].apply(print)

在图形中添加> foo > foo 函数时,Dask遍历字符串apply以推断输出的类型=> foo试图打开名为{{1}的文件}。

为了获得更好的理解,我鼓励您尝试:

imread

并尝试预测打印出的内容。

foo之后的延迟单元格

原因是ddf.apply(print, axis=1) 需要一个随后被调用的函数引用。通过创建调用延迟函数的lambda函数,基本上可以使函数双延迟。