在前一个帖子中,对以下问题给出了精彩的回答(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)
在内存使用方面提高效率?
答案 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
根据您对此处数据的处理方式,以稀疏形式提供数据可能有助于解决您的问题,而不会占用过多的内存。