在Dask中使用pandas cut函数

在Dask中使用pandas cut函数,pandas,dask,Pandas,Dask,如何在Dask中使用pd.cut()? 由于数据集很大,我无法在完成pd.cut()之前将整个数据集放入内存 正在熊猫中工作但需要更改为Dask的当前代码: import pandas as pd d = {'name': [1, 5, 1, 10, 5, 1], 'amount': [1, 5, 3, 8, 4, 1]} df = pd.DataFrame(data=d) #Groupby name and add column sum (of amounts) and count (nu

如何在Dask中使用pd.cut()? 由于数据集很大,我无法在完成pd.cut()之前将整个数据集放入内存

正在熊猫中工作但需要更改为Dask的当前代码:

import pandas as pd

d = {'name': [1, 5, 1, 10, 5, 1], 'amount': [1, 5, 3, 8, 4, 1]}
df = pd.DataFrame(data=d)

#Groupby name and add column sum (of amounts) and count (number of grouped rows)
df = (df.groupby('name')['amount'].agg(['sum', 'count']).reset_index().sort_values(by='name', ascending=True))
print(df.head(15))

#Groupby bins and chnage sum and count based on grouped rows
df = df.groupby(pd.cut(df['name'], 
           bins=[0,4,8,100], 
           labels=['namebin1', 'namebin2', 'namebin3']))['sum', 'count'].sum().reset_index()
print(df.head(15))
输出:

       name  sum  count
0  namebin1    5      3
1  namebin2    9      2
2  namebin3    8      1
我试过:

import pandas as pd
import dask.dataframe as dd

d = {'name': [1, 5, 1, 10, 5, 1], 'amount': [1, 5, 3, 8, 4, 1]}
df = pd.DataFrame(data=d)
df = dd.from_pandas(df, npartitions=2)

df = df.groupby('name')['amount'].agg(['sum', 'count']).reset_index()
print(df.head(15))

df = df.groupby(df.map_partitions(pd.cut, 
        df['name'],                  
        bins=[0,4,8,100], 
        labels=['namebin1', 'namebin2', 'namebin3']))['sum', 'count'].sum().reset_index()
print(df.head(15))
给出错误:
TypeError(“cut()为参数“bins”获取了多个值”)
您看到此错误的原因是
pd.cut()

您可以将其包装在自定义函数中,并调用该函数,如下所示:

import pandas as pd
import dask.dataframe as dd

def custom_cut(partition, bins, labels):
    result = pd.cut(x=partition["name"], bins=bins, labels=labels)
    return result

d = {'name': [1, 5, 1, 10, 5, 1], 'amount': [1, 5, 3, 8, 4, 1]}
df = pd.DataFrame(data=d)
df = dd.from_pandas(df, npartitions=2)

df = df.groupby('name')['amount'].agg(['sum', 'count']).reset_index()

df = df.groupby(df.map_partitions(custom_cut,               
        bins=[0,4,8,100], 
        labels=['namebin1', 'namebin2', 'namebin3']))[['sum', 'count']].sum().reset_index()

df.compute()

name        sum    count
namebin1    5      3
namebin2    9      2
namebin3    8      1

介意创建一些虚拟数据吗?请参阅@RayBell我编辑了这个问题,以便对我的代码和示例数据提供更多的见解。非常感谢。对我的小测试集有效,但对大测试集“被杀死”(可能内存不足)。我没有使用df.compute(),而是使用了一个打印(df.head()),但失败了。如何在不将整个数据集存储在内存中的情况下进行分组?我现在看到它已经在上一个操作中被“杀死”:df=(df.groupby('name')['amount'].agg(['sum','count'])。reset_index())(后面还有一个打印(df.head())。我发现这个打印触发了计算,所以我放弃了打印,现在重新运行。
pandas
中关于内存不足工作流的一般问题有很多答案。据我所知,您提供的代码在df.compute()之前不使用pandas,而是使用dask,对吗?中间没有任何指纹,它就因为内存不足而被杀死了。这对我来说似乎很奇怪,因为在生成3行3列df之前,所有内容都应该在磁盘上?不完全是这样
dask
将构建一个任务图(理想情况下是并行的),当您调用
compute()
或类似
head()
的隐式等价物时,将尝试执行它。到
compute()
点它之所以快,是因为创建任务很快……执行仍然会发生在内存中,或者分布在工作区中(如果有)。