使用 pandas 确定群组设置的变化

Identify change in group setting with pandas

我有一个包含三行的数据框。 'ID' 是一个人的唯一标识符。 'Group1' 和 'Group2' 是组标识符。

例如ID4一直在B组,现在在A组

| ID | Group1 | Group2 | |----|--------|--------| | 1 | A | A | | 2 | A | A | | 3 | A | A | | 4 | B | A | | 5 | B | B | | 6 | B | B | | 7 | C | C | | 8 | C | C | | 9 | C | C | | 10 | D | F | | 11 | D | F | | 12 | D | F | | 13 | D | F | | 14 | D | F |

我想知道这些组的一致性如何。以前在一个组中的相同成员是否又在一个组中?

所以根据组内的人来看,A组75%的人是一致的。 B组的66.6%是一致的。 C 组 100% 和 D 组 100% 的成员与 F 组的成员相同。

这将导致:

| ID | Group1 | Group2 | Cons | |----|--------|--------|--------| | 1 | A | A | 0.75 | | 2 | A | A | 0.75 | | 3 | A | A | 0.75 | | 4 | B | A | 0.75 | | 5 | B | B | 0.66 | | 6 | B | B | 0.66 | | 7 | C | C | 1.00 | | 8 | C | C | 1.00 | | 9 | C | C | 1.00 | | 10 | D | F | 1.00 | | 11 | D | F | 1.00 | | 12 | D | F | 1.00 | | 13 | D | F | 1.00 | | 14 | D | F | 1.00 |

你能帮我一些关于如何实现我正在寻找的东西的帮助吗?我试过 pct_change 但这行不通。

感谢您的帮助

编辑

非常感谢您的帮助。我尝试了更多数据,但仍然有一点问题。要确保:参与者只能从 Group1 切换到 Group2

这是我想要的更多数据。如您所见(以及上表中的 ID 4),很明显新组 2 BD BD GH A 占另一组的 33%,以及组 2 BD BD GH A G . 对于 ID 9 到 13,我想说第 2 组 AB 由 60% 的相同人员组成。对于 Group2 DF DC (ID 14) 我想说的是,这个组由 33% 的人组成。

ID Group1 Group2 Cons 0 A001 BD BD GH A BD BD GH A 0.333333 1 A002 BD BD GH A BD BD GH A 0.333333 2 A003 BD BD GH A BD BD GH A 0.333333 3 A004 BD BD GH A BD BD GH A G 0.333333 4 A005 BD BD GH A BD BD GH A G 0.333333 5 A006 BD BD GH A BD BD GH A G 0.333333 6 A007 BD BD GH A BD BD GH A F 0.333333 7 A008 BD BD GH A BD BD GH A F 0.333333 8 A009 BD BD GH A BD BD GH A F 0.333333 9 A010 AB AB 0.600000 10 A011 AB AB 0.600000 11 A012 AB AB 0.600000 12 A013 DF DC AB 0.600000 13 A014 DF DC AB 0.600000 14 A015 DF DC DF DC 0.333333 15 A016 AB CDE FGHI-JSHD JS AN CDE FGHI-JSHD JS 1.000000 16 A017 HD MV APS MG HD NV ALS BA HDJ 1.000000 17 A018 LA JF NV WJ LA JF NV OHB 1.000000

我觉得这是从现在开始的一小步,但我不知道如何调整这两个代码中的任何一个来解决我的问题。

我希望这有助于澄清我的问题。如果我对此不清楚,我很抱歉。

再次感谢您的帮助。

我们可以在这里使用两个 groupby,因为你想找到基于两列的一致性,即

# Find the consistency of group1 over group2 
one = df.groupby('Group1')['Group2'].apply(lambda x : sum(x == x.name)/len(x))

# Find the consistency of group2 over group1
two = df.groupby('Group2')['Group1'].apply(lambda x : sum(x == x.name)/len(x))

# Concat and find the min 
prob = pd.concat([one,two.reindex(one.index)],1).min(1)

# Map the values to the dataframe by replacing 0 with 1. 
df['Cons'] = df['Group1'].map(prob.where(prob!=0,1))
    ID Group1 Group2     Cons
0    1      A      A  0.750000
1    2      A      A  0.750000
2    3      A      A  0.750000
3    4      B      A  0.666667
4    5      B      B  0.666667
5    6      B      B  0.666667
6    7      C      C  1.000000
7    8      C      C  1.000000
8    9      C      C  1.000000
9   10      D      F  1.000000
10  11      D      F  1.000000
11  12      D      F  1.000000
12  13      D      F  1.000000
13  14      D      F  1.000000

上述解决方案处理两列的一致性。如果您只想找到 group1 相对于 group2 的一致性,那么我们可以使用

df.groupby('Group1')['Group2'].transform(lambda x : sum(x == x.name)/len(x)).replace(0,1)

您可以将 groupbytransform 与自定义一致性函数一起使用。首先,创建一些示例数据(注意:G_Source 对应于您的 G2G_Target 对应于您示例中的 G1):

创建示例数据

import pandas as pd
import numpy as np

values = np.random.randint(0, 5, size=(10, 2))
columns = ["G_Source", "G_Target"]

df = pd.DataFrame(values, columns=columns).sort_values("G_Source")
print(df)

    G_Source    G_Target
0   0           3
3   0           2
4   0           4
5   0           4
7   0           1
8   1           3
9   2           0
6   3           2
1   4           1
2   4           2

接下来,让我们定义一致性函数。基本上,我们正在寻找最常见值的计数。因此, value_countsmax.

结合使用很容易

定义一致性函数

def get_consistency(series):
    max_common = series.value_counts().max()
    size = series.shape[0]

    return max_common / size

Groupby 和转换

接下来,我们按源组 (G_Source) 分组,并通过 transform.

计算目标组 (G_Target) 的一致性
df["consistency"] = df.groupby("G_Source")["G_Target"].transform(get_consistency)
print(df)

    G_Source  G_Target  consistency
0   0         3         0.4
3   0         2         0.4
4   0         4         0.4
5   0         4         0.4
7   0         1         0.4
8   1         3         1.0
9   2         0         1.0
6   3         2         1.0
1   4         1         0.5
2   4         2         0.5