【问题标题】:assigning the value to a user depending on the cluster he comes from根据用户来自的集群将值分配给用户
【发布时间】:2018-02-22 22:22:03
【问题描述】:

我有两个数据框,一个包含喜欢歌曲的客户,另一个数据框包含用户及其集群。

数据 1:

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:

user    cluster
A   1
B   2
C   3
D   1
E   2
F   3

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

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

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

预期输出:

  user  song
    A   [33, 44]
    B   [66,55]
    C   [77]
    D   [11,22]
    E   [11,99]
    F   [66]

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    不容易:

    #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
    

    类似的解决方案:

    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
    

    【讨论】:

    • 一个人可以赞美任何人,对我来说是你......“上帝”。
    • @pylearner - 谢谢你,真的帮助我你非常好的样本数据;)祝你好运!
    • 在您的第一个解决方案中,您能否将 df1 设为具有两列用户和歌曲的数据框
    • 只需添加.reset_index() 喜欢df1 = df.groupby(['cluster']).apply(f).reset_index(level=0, drop=True).sort_index().reset_index(name='song')
    • jez,你能说出这个 x = x.apply(lambda x: x.index[x.isnull()].tolist(),1) 在你上面的解决方案 1 中做什么吗??
    【解决方案2】:

    使用集合进行比较。

    设置

    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]
    

    计算

    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)
    

    结果

      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}
    

    提取您需要的任何列;转换为列表很简单,即df[col] = df[col].map(list)

    说明

    有3个步骤:

    1. 将列表转换为集合,并将用户听到的歌曲汇总到集合。
    2. 执行映射以将所有数据放在一个表中。
    3. 添加一个计算两组之间差异的列。

    【讨论】:

    • 代替我的集群值,我有浮点值......它给我一个错误说“”TypeError:'float'对象不可迭代“”
    • @pylearner,我无法复制您的错误。如果您想找出问题所在,请随时提供minimal reproducible example
    猜你喜欢
    • 2023-03-05
    • 2016-06-07
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2011-11-08
    • 2016-11-15
    • 2019-11-30
    • 2018-01-08
    相关资源
    最近更新 更多