我有一个大约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
的任何对应行都符合某些条件。
答案 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)])