连接dask数据框和pandas数据框

时间:2019-02-15 03:13:08

标签: python pandas dataframe dask

我有一个大约2.5亿行(来自10Gb CSV文件)的简单数据帧(df)。我还有另一个25,000行的熊猫数据框(ndf)。我想通过重复每个项目10,000次来将pandas数据框的第一列添加到dask数据框。

这是我尝试的代码。我把问题缩小了。

import dask.dataframe as dd
import pandas as pd
import numpy as np

pd.DataFrame(np.random.rand(25000, 2)).to_csv("tempfile.csv")
df = dd.read_csv("tempfile.csv")
ndf = pd.DataFrame(np.random.randint(1000, 3500, size=2500))
df['Node'] = np.repeat(ndf[0], 10)

使用此代码,我最终会出错。

  

ValueError:并非所有分区都是已知的,无法对齐分区。请使用set_index设置索引。

我可以先执行一个reset_index(),然后执行一个set_index(),以使df.known_divisions True成为dask数据帧。但这是一项耗时的操作。有没有更好的更快的方法来做我想做的事情?我可以使用熊猫本身吗?

最终目标是从ndf查找行,其中df的任何对应行都符合某些条件。

2 个答案:

答案 0 :(得分:0)

使用相同的工作流程,您可以按照建议的here手动设置divisions

import dask.dataframe as dd
import pandas as pd
import numpy as np

pd.DataFrame(np.random.rand(25000, 2)).to_csv("tempfile.csv", index=False)
df = dd.read_csv("tempfile.csv")
ndf = pd.DataFrame(np.random.randint(1000, 3500, size=2500))


df.divisions = (0, len(df)-1)
df["Note"] = dd.from_array(np.repeat(ndf.values, 10))

我认为使用np.repeat并不是特别有效,特别是对于大df。

答案 1 :(得分:0)

您的基本算法是“我希望将df['Node']的前10个值设置为ndf的第一个值,接下来的10个值设置为ndf的下一个值, 等等”。在Dask中很难做到这一点的原因是,它不知道每个分区中有多少行:您正在从CSV读取数据,而您获得的X字节行数完全取决于每个部分的数据。其他格式可为您提供更多信息...

因此,您当然需要两次通过数据。您可以使用索引,以找出划分并可能进行一些排序。在我看来,您最容易做的就是简单地测量分度长度,然后获取每个分度的偏移量:

lengths = df.map_partitions(len).compute()
offsets = np.cumsum(lengths.values)
offsets -= offsets[0]

现在使用自定义延迟功能在零件上工作

@dask.delayed
def add_node(part, offset, ndf):
    index = pd.Series(range(offset, offset + len(part)) // 10,
                      index=part.index)  # 10 is the repeat factor
    part['Node'] = index.map(ndf)
    return part

df2 = dd.from_delayed([add_node(d, off, ndf) 
                       for d, off in zip(df.to_delayed(), offsets)])