Skip to main content
 首页 » 编程设计

python之Pandas 获得在同一列中一起使用的最频繁的值

2025年05月04日18over140

我有一个仅包含两列 user_id 和 channel 的数据集。 channel 列可以采用预定义列表 [a,b,c,d] 中的值。有多行具有相同的 user_id。每行可以包含上述任何 channel 。

如果我考虑每个用户访问的独特 channel ,哪一组出现频率最高?

示例数据框:

>>> df = pd.DataFrame([[1, 'a'], [1, 'b'], [1, 'b'], [1,'b'], [2,'c'], [2,'a'], [2,'a'], [2,'b'], [3,'a'], [3,'b']], columns=['user_id', 'Channel']) 
>>> df 
   user_id Channel 
0        1       a 
1        1       b 
2        1       b 
3        1       b 
4        2       c 
5        2       a 
6        2       a 
7        2       b 
8        3       a 
9        3       b 

预期的解决方案:

上面的例子是这样的:

  • 对于 user_id == 1,一组唯一的 channel 是 {a, b},并且对于该组合​​只计算一次。
  • 对于 user_id == 2 唯一 channel 集是 {a, b, c} 并且该组合计数一次。请注意,这不计入这些独特 channel 的任何子集。
  • 对于 user_id == 3,一组唯一的 channel 是 {a, b},并且该组合只计算一次。

如果我们计算每个 user_id 的一个唯一 channel 组合,我们应该得到

>>> df_result = pd.DataFrame([['a,b', 2], ['a,b,c', 1]], columns=['Channels_together', 'n']) 
>>> df_result 
  Channels_together  n 
0               a,b  2 
1             a,b,c  1 

我想出了一个解决方案,即旋转表,以便我得到 user_id 和列 a、b、c, d 然后为每个 Channel 列分配一个整数(如果不是 NA),然后跨列求和并将结果转换回每个组合。

我确信有更好的方法可以做到这一点,但我似乎无法找到方法。

请您参考如下方法:

您可以使用 groupby.apply(set) 然后使用 .value_counts 计算值:

df.groupby('user_id')['Channel'].apply(set).value_counts()\ 
  .reset_index(name='n')\ 
  .rename(columns={'index':'Channels_together'}) 

输出

  Channels_together  n 
0            {a, b}  2 
1         {a, c, b}  1 

如果您希望您的值采用 str 格式,我们可以编写一个 lambda 函数来对我们的集合进行排序并将其转换为字符串:

df.groupby('user_id')['Channel'].apply(lambda x: ', '.join(sorted(set(x)))).value_counts()\ 
  .reset_index(name='n')\ 
  .rename(columns={'index':'Channels_together'}) 

输出

  Channels_together  n 
0              a, b  2 
1           a, b, c  1