使用 pandas 组合组内的元素并获取跨组的出现次数
Combine elements within a group and get number of occurences across groups using 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”以老式方式获取“groups”列表长度的计数。
对于这部分,我担心“字母”列中的某些元素会有镜像对(如 group4 中的 B2B1),因此它们会有两个不同的计数,而我需要将它们作为一样。
有什么解决办法吗?
我也愿意接受更有效的方法来做到这一点。谢谢!
您要找的IIUCcombinations
:
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)
我正在分析的数据具有与此类似的结构:
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”以老式方式获取“groups”列表长度的计数。
对于这部分,我担心“字母”列中的某些元素会有镜像对(如 group4 中的 B2B1),因此它们会有两个不同的计数,而我需要将它们作为一样。
有什么解决办法吗? 我也愿意接受更有效的方法来做到这一点。谢谢!
您要找的IIUCcombinations
:
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)