python dataframe - lambda X 函数 - 更高效的实现可能吗?

python dataframe - lambda X function - more efficient implementation possible?

在之前的帖子中,对以下问题(Pandas: reshaping data)给出了精彩的回答。 目标是通过以下方式将包含列表的 pandas 系列重塑为 pandas 数据框:

In [9]: s = Series([list('ABC'),list('DEF'),list('ABEF')])

In [10]: s
Out[10]: 
0       [A, B, C]
1       [D, E, F]
2    [A, B, E, F]
dtype: object

应该变成这样:

Out[11]: 
   A  B  C  D  E  F
0  1  1  1  0  0  0
1  0  0  0  1  1  1
2  1  1  0  0  1  1

也就是说,创建一个数据框,其中系列列表中的每个元素都成为一列。对于系列中的每个元素,都会在数据框中创建一行。对于列表中的每个元素,将 1 分配给相应的数据框列(否则为 0)。我知道措辞可能很繁琐,但希望上面的例子很清楚。

用户 Jeff (https://whosebug.com/users/644898/jeff) 的精彩回应是编写了这行简单而强大的代码:

In [11]: s.apply(lambda x: Series(1,index=x)).fillna(0)

将 [10] 转换为 [11]。

这行代码对我来说非常有用,但是我 运行 遇到了一系列大约 50K 元素和所有列表中大约 100K 不同元素的内存问题。我的机器有16G内存。在求助于更大的机器之前,我想考虑一个更高效的实现上面的功能。

有谁知道如何重新实现上面的行:

In [11]: s.apply(lambda x: Series(1,index=x)).fillna(0)

在内存使用方面提高效率?

您可以尝试将数据帧分成多个块并边写边写入文件,如下所示:

chunksize = 10000
def f(df):
    return f.apply(lambda x: Series(1,index=x)).fillna(0)

with open('out.csv','w') as f:
   f.write(df.ix[[]].to_csv()) #write the header
   for chunk in df.groupby(np.arange(len(df))//chunksize):
      f.write(f(chunk).to_csv(header=None))

如果内存使用是问题,那么稀疏矩阵解决方案似乎会更好。 Pandas 并不真正支持稀疏矩阵,但您可以像这样使用 scipy.sparse

data = pd.Series([list('ABC'),list('DEF'),list('ABEF')])

from scipy.sparse import csr_matrix
cols, ind = np.unique(np.concatenate(data), return_inverse=True)
indptr = np.cumsum([0] + list(map(len, data)))
vals = np.ones_like(ind)
M = csr_matrix((vals, ind, indptr))

此稀疏矩阵现在包含与 pandas 解相同的数据,但未明确存储零。我们可以通过将稀疏矩阵转换为数据帧来确认这一点:

>>> pd.DataFrame(M.toarray(), columns=cols)
   A  B  C  D  E  F
0  1  1  1  0  0  0
1  0  0  0  1  1  1
2  1  1  0  0  1  1

根据您对此处数据的处理方式,采用稀疏形式可能有助于在不使用过多内存的情况下解决您的问题。