Python dask可以用于分组并从核心重新编码吗?

Python dask可以用于分组并从核心重新编码吗?,python,pandas,dask,Python,Pandas,Dask,我有8GB的csv文件和8GB的RAM。在这种形式下,每个文件每行有两个字符串: a,c c,a f,g a,c c,a b,f c,a 对于较小的文件,我删除重复项,计算前两列中每行的副本数,然后将字符串重新编码为整数: 这使得: ID_0 ID_1 count 0 0 1 2 1 1 0 3 2 2 4 1 3 4 3 1 这正是这个玩具示例所需要的 对于较大的文件,由于缺少

我有8GB的csv文件和8GB的RAM。在这种形式下,每个文件每行有两个字符串:

a,c
c,a
f,g
a,c
c,a
b,f
c,a
对于较小的文件,我删除重复项,计算前两列中每行的副本数,然后将字符串重新编码为整数:

这使得:

   ID_0  ID_1  count
0     0     1      2
1     1     0      3
2     2     4      1
3     4     3      1
这正是这个玩具示例所需要的

对于较大的文件,由于缺少RAM,我无法执行这些步骤

我可以想象,可以将unix排序和定制python解决方案结合起来,对数据进行多次传递,以处理我的数据集。但有人认为达斯克可能是合适的。看完这些文件后,我仍然不清楚

dask可以用来做这种类型的核外处理吗?或者有其他的核外解决方案吗


假设分组的数据帧适合您的内存,那么您对代码所做的更改应该非常小。以下是我的尝试:

import pandas as pd
from dask import dataframe as dd
from sklearn.preprocessing import LabelEncoder

# import the data as dask dataframe, 100mb per partition
# note, that at this point no data is read yet, dask will read the files
# once compute or get is called.
df = dd.read_csv("file.txt", header=None, prefix="ID_", blocksize=100000000)

# Perform the groupby (before converting letters to digits).
# For better understanding, let's split this into two parts:
#     (i) define the groupby operation on the dask dataframe and call compute()
#     (ii) compute returns a pandas dataframe, which we can then use for further analysis
pandas_df = df.groupby(['ID_0', 'ID_1']).apply(lambda x: len(x), columns=0).compute()
pandas_df = pandas_df.rename('count').reset_index()

# Initialize the LabelEncoder.
le = LabelEncoder()
le.fit(pandas_df[['ID_0', 'ID_1']].values.flat)

# Convert to digits.
pandas_df[['ID_0', 'ID_1']] = pandas_df[['ID_0', 'ID_1']].apply(le.transform)
pandas中一个可能的解决方案是分块读取文件(将chunksize参数传递给read_csv),在单个块上运行groupby并组合结果


以下是使用纯python解决问题的方法:

counts = {}
with open('data') as fp:
    for line in fp:
        id1, id2 = line.rstrip().split(',')
        counts[(id1, id2)] = 1 + counts.get((id1, id2), 0)

df = pd.DataFrame(data=[(k[0], k[1], v) for k, v in counts.items()],
                  columns=['ID_0', 'ID_1', 'count'])
# apply label encoding etc.
le = LabelEncoder()
le.fit(df[['ID_0', 'ID_1']].values.flat)

# Convert to digits.
df[['ID_0', 'ID_1']] = df[['ID_0', 'ID_1']].apply(le.transform)

dask是一个明智的选择:看看下面的答案,如果遇到问题不要放弃。谢谢。你的建议似乎很难,因为我不确定你会如何结合结果。您能为此添加一些代码吗?pandas解决方案将涉及组合各个groupby结果(通过为每个区块添加(ID_0,ID_1)-元组的计数)。解决您的具体问题的最简单的方法是简单地读取文件,边走边数。我已经添加了这方面的代码——或者说您更喜欢执行大型groupbys的常规方法?谢谢您的编辑。使用dict的一个问题是,它在Python中的内存效率非常低。LabelEncoder在大型数据集上的速度非常慢。这是一个已知的缺陷,但同时dict的速度要快得多。
counts = {}
with open('data') as fp:
    for line in fp:
        id1, id2 = line.rstrip().split(',')
        counts[(id1, id2)] = 1 + counts.get((id1, id2), 0)

df = pd.DataFrame(data=[(k[0], k[1], v) for k, v in counts.items()],
                  columns=['ID_0', 'ID_1', 'count'])
# apply label encoding etc.
le = LabelEncoder()
le.fit(df[['ID_0', 'ID_1']].values.flat)

# Convert to digits.
df[['ID_0', 'ID_1']] = df[['ID_0', 'ID_1']].apply(le.transform)