如何从一张长桌子上高效地创建Sparsetalaframe?

2024-04-25 10:23:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我可以把Pandas作为一个SQL结构来读取:

user_id    value
1          100
1          200
2          100
4          200

它是一个矩阵的表示,它的所有值都是1或0。该矩阵的密集表示如下:

^{pr2}$

通常,要进行这种转换,您可以使用pivot,但是在我的第一个表中有几千万或数亿行的情况下,我们会得到一个大而密集的矩阵,它充满了零,这是非常昂贵的。您可以将其转换为稀疏,但要达到这一目标需要大量资源。在

现在我正在研究一个解决方案,为每个用户分配行号,进行排序,然后在重新组合成sparsedaframe之前将“value”列拆分为SparseSeries。有更好的方法吗?在


Tags: 用户id目标pandassqlvalue情况矩阵
1条回答
网友
1楼 · 发布于 2024-04-25 10:23:00

我找到了一个解决办法,尽管有点不完美。在

我们可以做的是从列中手动创建一些Pandas SparseSeries,将它们组合成dict,然后将dict转换为一个DataFrame(而不是sparsedaframe)。Casting as sparsedaframe当前遇到了一个不成熟的构造函数,它将整个对象解构为稠密的,然后返回到稀疏的形式,而不管输入是什么。然而,将稀疏系列构建到传统的数据帧中,可以保持稀疏性,但会创建一个可行的、其他方面完整的数据帧对象。在

下面是一个演示如何做到这一点,写的更多的是为了清晰而不是为了表现。我自己实现的一个不同之处是,我创建了稀疏向量dict作为dict理解,而不是循环。在

import pandas
import numpy

df = pandas.DataFrame({'user_id':[1,2,1,4],'value':[100,100,200,200]})

# Get unique users and unique features
num_rows = len(df['user_id'].unique())
num_features = len(df['value'].unique())
unique_users = df['user_id'].unique().copy()
unique_features = df['value'].unique().copy()
unique_users.sort()
unique_features.sort()


# assign each user_id to a row_number
user_lookup = pandas.DataFrame({'uid':range(num_rows), 'user_id':unique_users})


vec_dict = {}

# Create a sparse vector for each feature
for i in range(num_features):
    users_with_feature = df[df['value']==unique_features[i]]['user_id']

    uid_rows = user_lookup[user_lookup['user_id'].isin(users_with_feature)]['uid']

    vec = numpy.zeros(num_rows)
    vec[uid_rows] = 1

    sparse_vec = pandas.Series(vec).to_sparse(fill_value=0)

    vec_dict[unique_features[i]] = sparse_vec


my_pandas_frame = pandas.DataFrame(vec_dict)    
my_pandas_frame = my_pandas_frame.set_index(user_lookup['user_id']) 

结果:

^{pr2}$

完整,但仍然稀疏。有几个注意事项,如果你做了一个简单的复制或子集不到位,那么它会忘记自己,并试图重铸到稠密,但就我的目的而言,我很满意它。在

相关问题 更多 >