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

时间:2015-10-23 02:40:08

标签: list memory pandas dataframe series

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

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://stackoverflow.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)

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

2 个答案:

答案 0 :(得分:1)

您可以尝试将数据框分成块并随时写入文件,如下所示:

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))

答案 1 :(得分:1)

如果内存使用是问题,似乎稀疏矩阵解决方案会更好。 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

根据您对此处数据的处理方式,以稀疏形式提供数据可能有助于解决您的问题,而不会占用过多的内存。