簡體   English   中英

連接dask數據幀和pandas數據幀

[英]Concatenating a dask dataframe and a pandas dataframe

我有一個約有2.5億行的dask數據幀( df )(來自一個10Gb的CSV文件)。 我有另外25,000行的pandas數據幀( 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()來使dask數據幀的df.known_divisions True 但這是一項耗時的操作。 有沒有更好的方法來做我想做的事情? 我可以用熊貓本身做到這一點嗎?

最終目標是從ndf中查找行,其中來自df任何相應行與某些條件匹配。

你的基本的算法是:“我想的第一個10個值df['Node']設置為第一值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)])

使用相同的工作流程,您可以按照此處的建議手動設置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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM