首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据用户来自的集群将该值分配给他

根据用户来自的集群将该值分配给他
EN

Stack Overflow用户
提问于 2018-02-22 12:40:08
回答 2查看 41关注 0票数 1

我有两个dataframe,一个与喜欢歌曲的客户一起使用,另一个由用户和他们的集群组成。

数据1:

代码语言:javascript
复制
user    song
A   11
A   22
B   99
B   11
C   11
D   44
C   66
E   66
D   33
E   55
F   11
F   77

数据2:

代码语言:javascript
复制
user    cluster
A   1
B   2
C   3
D   1
E   2
F   3

使用上述数据集,我能够实现该集群的用户所听的所有歌曲。

代码语言:javascript
复制
cluster songs
    1   [11, 22, 33, 44]
    2   [11, 99, 66, 55] 
    3   [11,66,88,77]

我需要将特定集群的歌曲分配给还没有听过的特定用户。在我的预期输出A属于集群1,他还没有听歌曲33和44..so我的输出应该如下所示。B属于集群2,B没有听66和55首歌曲,B的输出如下所示。

预期产出:

代码语言:javascript
复制
  user  song
    A   [33, 44]
    B   [66,55]
    C   [77]
    D   [11,22]
    E   [11,99]
    F   [66]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-22 12:54:08

不容易:

代码语言:javascript
复制
#add column and remove duplicates
df = pd.merge(df1, df2, on='user', how='left').drop_duplicates(['user','song'])

def f(x):
    #for each group reshape
    x = x.pivot('user','song','cluster')
    #get all columns values if NaNs in data  
    x = x.apply(lambda x: x.index[x.isnull()].tolist(),1)
    return x

df1 = df.groupby(['cluster']).apply(f).reset_index(level=0, drop=True).sort_index()
user
A    [33, 44]
B    [55, 66]
C        [77]
D    [11, 22]
E    [11, 99]
F        [66]
dtype: object

类似的解决方案:

代码语言:javascript
复制
df = pd.merge(df1, df2, on='user', how='left').drop_duplicates(['user','song'])
df1 = (df.groupby(['cluster']).apply(lambda x: x.pivot('user','song','cluster').isnull())
        .fillna(False)
        .reset_index(level=0, drop=True)
        .sort_index())

#replace each True by value of column
s = np.where(df1, ['{}, '.format(x) for x in df1.columns.astype(str)], '')
#remove empty values
s1 = pd.Series([''.join(x).strip(', ') for x in s], index=df1.index)
print (s1)
user
A    33, 44
B    55, 66
C        77
D    11, 22
E    11, 99
F        66
dtype: object
票数 1
EN

Stack Overflow用户

发布于 2018-02-22 12:54:15

使用集合进行比较。

设置

代码语言:javascript
复制
df1

#    user  song
# 0     A    11
# 1     A    22
# 2     B    99
# 3     B    11
# 4     C    11
# 5     D    44
# 6     C    66
# 7     E    66
# 8     D    33
# 9     E    55
# 10    F    11
# 11    F    77

df2

#   user  cluster
# 0    A        1
# 1    B        2
# 2    C        3
# 3    D        1
# 4    E        2
# 5    F        3

df3

#    cluster             songs
# 0        1  [11, 22, 33, 44]
# 1        2  [11, 99, 66, 55]
# 2        3  [11, 66, 88, 77]

计算

代码语言:javascript
复制
df = df1.groupby('user')['song'].apply(set)\
        .reset_index().rename(columns={'song': 'heard'})

df['all'] = df['user'].map(df2.set_index('user')['cluster'])\
                      .map(df3.set_index('cluster')['songs'])\
                      .map(set)

df['not heard'] = df.apply(lambda row: row['all'] - row['heard'], axis=1)

结果

代码语言:javascript
复制
  user     heard               all not heard
0    A  {11, 22}  {33, 11, 44, 22}  {33, 44}
1    B  {11, 99}  {99, 66, 11, 55}  {66, 55}
2    C  {66, 11}  {88, 66, 11, 77}  {88, 77}
3    D  {33, 44}  {33, 11, 44, 22}  {11, 22}
4    E  {66, 55}  {99, 66, 11, 55}  {11, 99}
5    F  {11, 77}  {88, 66, 11, 77}  {88, 66}

提取所需的任何列;将其转换为list非常简单,即df[col] = df[col].map(list)

解释

有三个步骤:

  1. 将列表转换为集合,并将用户所听到的歌曲聚合到集合。
  2. 执行映射,将所有数据放在一个表中。
  3. 添加一个列来计算2组之间的差额。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48927671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档