使用 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)
您可以将 groupby
和 transform
与自定义一致性函数一起使用。首先,创建一些示例数据(注意:G_Source 对应于您的 G2 而 G_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_counts
与 max
.
结合使用很容易
定义一致性函数
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
我有一个包含三行的数据框。 '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)
您可以将 groupby
和 transform
与自定义一致性函数一起使用。首先,创建一些示例数据(注意:G_Source 对应于您的 G2 而 G_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_counts
与 max
.
定义一致性函数
def get_consistency(series):
max_common = series.value_counts().max()
size = series.shape[0]
return max_common / size
Groupby 和转换
接下来,我们按源组 (G_Source) 分组,并通过 transform.
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