繁体   English   中英

使用 Groupby 计算一列中的唯一组合

[英]count unique combination in one column using Groupby

我有一个 dataframe,我正在尝试创建新列以显示不同组内不同组合的出现。 我发现的解决方案是 2 个或更多列而不是一个列的所有值组合。 因此,希望有人能提供帮助。

样品 df:

╔════╦═════╗
║ id ║ tag ║
╠════╬═════╣
║ a  ║   1 ║
║ a  ║   1 ║
║ a  ║   2 ║
║ a  ║   2 ║
║ a  ║   3 ║
║ a  ║   3 ║
║ b  ║   2 ║
║ b  ║   2 ║
║ b  ║   2 ║
║ b  ║   3 ║
║ b  ║   3 ║
║ b  ║   3 ║
╚════╩═════╝

output 希望获得:

╔════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╗
║ id ║ tag ║ 1,1 ║ 1,2 ║ 1,3 ║ 2,2 ║ 2,3 ║ 3,3 ║
╠════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣
║ a  ║   1 ║   1 ║   4 ║   4 ║   1 ║   4 ║   1 ║
║ a  ║   1 ║   1 ║   4 ║   4 ║   1 ║   4 ║   1 ║
║ a  ║   2 ║   1 ║   4 ║   4 ║   1 ║   4 ║   1 ║
║ a  ║   2 ║   1 ║   4 ║   4 ║   1 ║   4 ║   1 ║
║ a  ║   3 ║   1 ║   4 ║   4 ║   1 ║   4 ║   1 ║
║ a  ║   3 ║   1 ║   4 ║   4 ║   1 ║   4 ║   1 ║
║ b  ║   2 ║   0 ║   0 ║   0 ║   3 ║   9 ║   3 ║
║ b  ║   2 ║   0 ║   0 ║   0 ║   3 ║   9 ║   3 ║
║ b  ║   2 ║   0 ║   0 ║   0 ║   3 ║   9 ║   3 ║
║ b  ║   3 ║   0 ║   0 ║   0 ║   3 ║   9 ║   3 ║
║ b  ║   3 ║   0 ║   0 ║   0 ║   3 ║   9 ║   3 ║
║ b  ║   3 ║   0 ║   0 ║   0 ║   3 ║   9 ║   3 ║
╚════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╝

示例 df 代码:

data = {
    "id": ['a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b'],
    "tag": [1, 1, 2, 2, 3, 3, 2, 2, 2, 3, 3, 3]}

df = pd.DataFrame(data)

澄清一下:“col“x,y”是按 id 分组的标签值的组合”,如@Chrysophylaxs 所述(谢谢)。

好心提醒

我在这里得到了答案:

data = {
    "id": ['a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b'],
    "tag": [1, 1, 2, 2, 3, 3, 2, 2, 2, 3, 3, 3]}

df = pd.DataFrame(data)

from itertools import combinations

df['combinations'] = df.groupby(['id']).transform(lambda x: str(list(combinations(x.to_list(), 2))))
df['combinations'] = df['combinations'].apply(lambda x: x.replace('[', '').replace(']', '').replace('),', '*').replace(', ','-').replace('*',',').replace('(','').replace(')','').replace(' ','')).str.split(',')
df2 = df.drop_duplicates(['combinations'])

x = df2.explode('combinations')
x = x.drop('tag', axis=1).groupby(['id', 'combinations']).value_counts().unstack().reset_index().fillna(0)
df.merge(x, on='id', how='left').drop('combinations', axis=1)

Output:

    id  tag 1-1 1-2 1-3 2-2 2-3 3-3
0   a   1   1.0 4.0 4.0 1.0 4.0 1.0
1   a   1   1.0 4.0 4.0 1.0 4.0 1.0
2   a   2   1.0 4.0 4.0 1.0 4.0 1.0
3   a   2   1.0 4.0 4.0 1.0 4.0 1.0
4   a   3   1.0 4.0 4.0 1.0 4.0 1.0
5   a   3   1.0 4.0 4.0 1.0 4.0 1.0
6   b   2   0.0 0.0 0.0 3.0 9.0 3.0
7   b   2   0.0 0.0 0.0 3.0 9.0 3.0
8   b   2   0.0 0.0 0.0 3.0 9.0 3.0
9   b   3   0.0 0.0 0.0 3.0 9.0 3.0
10  b   3   0.0 0.0 0.0 3.0 9.0 3.0
11  b   3   0.0 0.0 0.0 3.0 9.0 3.0

这是另一个答案的变体:

s = df.groupby('id')['tag'].agg(lambda x: list(itertools.combinations(x,2))).explode()

(df.join(
    s.groupby([pd.Grouper(level=0),s]).size().unstack()
    .rename('{0[0]}-{0[1]}'.format,axis=1),on = 'id')
.fillna(0))

Output:

   id  tag  1-1  1-2  1-3  2-2  2-3  3-3
0   a    1  1.0  4.0  4.0  1.0  4.0  1.0
1   a    1  1.0  4.0  4.0  1.0  4.0  1.0
2   a    2  1.0  4.0  4.0  1.0  4.0  1.0
3   a    2  1.0  4.0  4.0  1.0  4.0  1.0
4   a    3  1.0  4.0  4.0  1.0  4.0  1.0
5   a    3  1.0  4.0  4.0  1.0  4.0  1.0
6   b    2  0.0  0.0  0.0  3.0  9.0  3.0
7   b    2  0.0  0.0  0.0  3.0  9.0  3.0
8   b    2  0.0  0.0  0.0  3.0  9.0  3.0
9   b    3  0.0  0.0  0.0  3.0  9.0  3.0
10  b    3  0.0  0.0  0.0  3.0  9.0  3.0
11  b    3  0.0  0.0  0.0  3.0  9.0  3.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM