我有一个这样的熊猫数据框:
a other-columns
0.3 0.2 0.0 0.0 0.0... ....
我想将列a
转换为SciPy稀疏CSR矩阵。 a
是概率分布。我想进行转换而无需将a
扩展为多列。
这是将a
扩展为多列的幼稚解决方案:
df = df.join(df['a'].str.split(expand = True).add_prefix('a')).drop(['a'], axis = 1)
df_matrix = scipy.sparse.csr_matrix(df.values)
但是,我不想扩展为多列,因为它会占用大量内存。是否可以仅将a
保留在1列中?
编辑(最小可复制示例):
import pandas as pd
from scipy.sparse import csr_matrix
d = {'a': ['0.05 0.0', '0.2 0.0']}
df = pd.DataFrame(data=d)
df = df.join(df['a'].str.split(expand = True).add_prefix('a')).drop(['a'], axis = 1)
df = df.astype(float)
df_matrix = scipy.sparse.csr_matrix(df.values)
df_matrix
输出:
<2x2 sparse matrix of type '<class 'numpy.float64'>'
with 2 stored elements in Compressed Sparse Row format>
我想实现以上目标,但又不要分成多列。另外,在我的真实文件中,我有36个长度的字符串(用空格分隔)列和数百万行。确保所有行都包含36个空格。
答案 0 :(得分:1)
您无需展开即可从列中获取密集数组:
In [179]: df = pd.DataFrame(data=d)
例如
In [180]: np.array(df['a'].str.split().tolist(),float)
Out[180]:
array([[0.05, 0. ],
[0.2 , 0. ]])
但是我怀疑这是否可以节省很多内存(尽管我对DataFrame
内存使用只有粗略的了解。
您可以将每个字符串转换为稀疏矩阵:
In [190]: def foo(astr):
...: alist = astr.split()
...: arr = np.array(alist, float)
...: return sparse.coo_matrix(arr)
In [191]: alist = [foo(row) for row in df['a']]
In [192]: alist
Out[192]:
[<1x2 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in COOrdinate format>,
<1x2 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in COOrdinate format>]
In [193]: sparse.vstack(alist)
Out[193]:
<2x2 sparse matrix of type '<class 'numpy.float64'>'
with 2 stored elements in COOrdinate format>
我尝试直接从coo
中制作alist
,但这并没有消除零。转换的次数也很多,但是如果足够稀疏(5%或更少),则可以节省大量内存(如果没有时间的话)。
sparse.vstack
组合了来自组件矩阵的data,rows,cols
值以定义新的coo
矩阵。如果不是最快的话,这是组合稀疏矩阵的最直接方法。
好像我也可以使用apply
In [205]: df['a'].apply(foo)
Out[205]:
0 (0, 0)\t0.05
1 (0, 0)\t0.2
Name: a, dtype: object
In [206]: df['a'].apply(foo).values
Out[206]:
array([<1x2 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in COOrdinate format>,
<1x2 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in COOrdinate format>], dtype=object)
In [207]: sparse.vstack(df['a'].apply(foo))
Out[207]:
<2x2 sparse matrix of type '<class 'numpy.float64'>'
with 2 stored elements in COOrdinate format>
答案 1 :(得分:1)
此外,在我的真实文件中,我有36个长度的字符串(用空格分隔)列和数百万行。确保所有行都包含36个空格。
Convert large csv to sparse matrix for use in sklearn
我不能高估你不应该做多少跟在这句话后面的事情。
import pandas as pd
import numpy as np
from scipy import sparse
df = pd.DataFrame({'a': ['0.05 0.0', '0.2 0.0'] * 100000})
chunksize = 10000
sparse_coo = []
for i in range(int(np.ceil(df.shape[0]/chunksize))):
chunk = df.iloc[i * chunksize:min(i * chunksize +chunksize, df.shape[0]), :]
sparse_coo.append(sparse.coo_matrix(chunk['a'].apply(lambda x: [float(y) for y in x.split()]).tolist()))
sparse_coo = sparse.vstack(sparse_coo)