首页 > 解决方案 > 组合一个组内的元素并使用 pandas 获得跨组的出现次数

问题描述

我正在分析的数据具有与此类似的结构:

df = pd.DataFrame(
    {
        "group": ["group1", "group1", "group2", "group2", "group2", "group3", "group3", "group3", "group4", "group4", "group4", "group4", "group5", "group5"],
        "letter": ["B1", "B2", "B1", "B2", "B3", "B1", "B2", "B4", "B2", "B1", "B3", "B4", "B3", "B4"]
    })

我想获得每个组中元素的可能组合,其中顺序并不重要。例如,对于 group2 我想获得这样的东西:

group   letter_x  letter_y
group2     B1       B2
group2     B1       B3
group2     B2       B3

我已经将 df 与其自身合并以获得组合,然后以这种方式摆脱相等的值(例如 B1B1):

df_merge = df.merge(df, left_on='group', right_on='group', how="outer")
df_merge = df_merge[df_merge['letter_x'] != df_merge['letter_y']]

但我无法摆脱对称对,这意味着,例如,对于 group2 我获得:

group   letter_x  letter_y
group2     B1       B2
group2     B1       B3
group2     B2       B1
group2     B2       B3
group2     B3       B1
group2     B3       B2

有任何想法吗?

另一方面,我想在不同的数据帧中跨组获取每对的出现次数。例如:

letter_x  letter_y  count  groups
  B1        B2        4    (group1,group2,group3,group4)
  B1        B3        2    (group2,group4)
  B1        B4        2    (group3,group4)
  ...

我的意图是应用这样的东西:

df_overlap = df_merge.groupby(['letter_x', 'letter_y']).agg(lambda x: tuple(x)).reset_index()

然后使用“for”以老式方式获取具有“组”列表长度的计数。

对于这一部分,我担心“字母”列中的某些元素将具有镜像对(如 group4 中的 B2B1),因此它们将具有两个不同的计数,而我需要将它们视为相同。

有什么解决办法吗?我也愿意接受更有效的方法来做到这一点。谢谢!

标签: pythonpandasmerge

解决方案


您正在寻找的 IIUC combinations

from itertools import combinations

out = (df.sort_values(["group", "letter"])
         .groupby("group")["letter"]
         .apply(lambda d: pd.DataFrame(combinations(d, 2),  columns=["letter_x", "letter_y"]))
         .droplevel(1).reset_index())

print (out.groupby(["letter_x","letter_y"])["group"].agg(["count", tuple]).reset_index())

  letter_x letter_y  count                             tuple
0       B1       B2      4  (group1, group2, group3, group4)
1       B1       B3      2                  (group2, group4)
2       B1       B4      2                  (group3, group4)
3       B2       B3      2                  (group2, group4)
4       B2       B4      2                  (group3, group4)
5       B3       B4      2                  (group4, group5)

推荐阅读