根据 Python 中的 groupby 从数据框中两列的所有可能组合创建列
Create column from all possible combination of two columns in dataframe based on groupby in Python
我有一个如下所示的数据框
id
group
log
10
UU1Q
23
10
UU1Q
12
10
UU2Q
15
11
UU2Q
17
11
UU3Q
35.6
11
UU1Q
29.8
11
UU1Q
33
11
UU1Q
44
13
UU2Q
17.77
13
UU2Q
19.90
13
UU2Q
55
14
UU3Q
33
15
UU3Q
22
对于每个 ID 和组,我想在新列中创建数据框中存在的所有可能的日志值组合。
期望输出
id
group
log
new_col
10
UU1Q
23
(23,23)
10
UU1Q
12
(23,12)
10
UU2Q
15
(15,15)
11
UU2Q
17
(17,17)
11
UU3Q
35.6
(35.6,35.6)
11
UU1Q
29.8
(29.8, 29.8)
11
UU1Q
33
(29.8,33)
11
UU1Q
44
(29.8,44)
11
UU1Q
(33,44)
13
UU2Q
17.77
(17.77,17.77)
13
UU2Q
19.90
(17.77,19.90)
13
UU2Q
55
(17.77,55)
13
UU2Q
(19.90,55)
14
UU3Q
33
(33,33)
15
UU3Q
22
(22,22)
我使用了 shift 函数,但它只生成与下一个匹配单元格的组合。我想得到每个组中所有可能的组合。
dummy['new'] = dummy.groupby(['ID', 'group'])['log'].shift()
这将 return 所需的输出:
df.groupby(['id','group'], as_index=False).agg({'log':lambda x: list(x)})
Output:
id group log
0 10 UU1Q [23.0, 12.0]
1 10 UU2Q [15.0]
2 11 UU1Q [29.8, 33.0, 44.0]
3 11 UU2Q [17.0]
4 11 UU3Q [35.6]
5 13 UU2Q [17.77, 19.9, 55.0]
6 14 UU3Q [33.0]
7 15 UU3Q [22.0]
这很接近所需要的 - 添加了所有组合,如果每组创建一个元素具有相同值的元组:
from itertools import combinations
df = (df.groupby(['id','group'])['log']
.apply(lambda x: list(combinations(x, 2)) if len(x) > 1 else [(*x, *x)])
.explode()
.reset_index(name='comb'))
print (df)
id group comb
0 10 UU1Q (23.0, 12.0)
1 10 UU2Q (15.0, 15.0)
2 11 UU1Q (29.8, 33.0)
3 11 UU1Q (29.8, 44.0)
4 11 UU1Q (33.0, 44.0)
5 11 UU2Q (17.0, 17.0)
6 11 UU3Q (35.6, 35.6)
7 13 UU2Q (17.77, 19.9)
8 13 UU2Q (17.77, 55.0)
9 13 UU2Q (19.9, 55.0)
10 14 UU3Q (33.0, 33.0)
11 15 UU3Q (22.0, 22.0)
或者可以为每个 ['id','group'] 创建第一行的相同值元组并连接到由组合填充的 DataFrame df1
:
from itertools import combinations
df1 = (df.groupby(['id','group'])['log']
.apply(lambda x: list(combinations(x, 2)))
.explode()
.dropna()
.reset_index(name='comb'))
df2 = df.groupby(['id','group']).head(1).copy()
df2['comb'] = df2.pop('log').map(lambda x: (x,x))
df = pd.concat([df2, df1]).sort_values(['id','group'], ignore_index=True)
print (df)
id group comb
0 10 UU1Q (23.0, 23.0)
1 10 UU1Q (23.0, 12.0)
2 10 UU2Q (15.0, 15.0)
3 11 UU1Q (29.8, 29.8)
4 11 UU1Q (29.8, 33.0)
5 11 UU1Q (29.8, 44.0)
6 11 UU1Q (33.0, 44.0)
7 11 UU2Q (17.0, 17.0)
8 11 UU3Q (35.6, 35.6)
9 13 UU2Q (17.77, 17.77)
10 13 UU2Q (17.77, 19.9)
11 13 UU2Q (17.77, 55.0)
12 13 UU2Q (19.9, 55.0)
13 14 UU3Q (33.0, 33.0)
14 15 UU3Q (22.0, 22.0)
我有一个如下所示的数据框
id | group | log |
---|---|---|
10 | UU1Q | 23 |
10 | UU1Q | 12 |
10 | UU2Q | 15 |
11 | UU2Q | 17 |
11 | UU3Q | 35.6 |
11 | UU1Q | 29.8 |
11 | UU1Q | 33 |
11 | UU1Q | 44 |
13 | UU2Q | 17.77 |
13 | UU2Q | 19.90 |
13 | UU2Q | 55 |
14 | UU3Q | 33 |
15 | UU3Q | 22 |
对于每个 ID 和组,我想在新列中创建数据框中存在的所有可能的日志值组合。 期望输出
id | group | log | new_col |
---|---|---|---|
10 | UU1Q | 23 | (23,23) |
10 | UU1Q | 12 | (23,12) |
10 | UU2Q | 15 | (15,15) |
11 | UU2Q | 17 | (17,17) |
11 | UU3Q | 35.6 | (35.6,35.6) |
11 | UU1Q | 29.8 | (29.8, 29.8) |
11 | UU1Q | 33 | (29.8,33) |
11 | UU1Q | 44 | (29.8,44) |
11 | UU1Q | (33,44) | |
13 | UU2Q | 17.77 | (17.77,17.77) |
13 | UU2Q | 19.90 | (17.77,19.90) |
13 | UU2Q | 55 | (17.77,55) |
13 | UU2Q | (19.90,55) | |
14 | UU3Q | 33 | (33,33) |
15 | UU3Q | 22 | (22,22) |
我使用了 shift 函数,但它只生成与下一个匹配单元格的组合。我想得到每个组中所有可能的组合。
dummy['new'] = dummy.groupby(['ID', 'group'])['log'].shift()
这将 return 所需的输出:
df.groupby(['id','group'], as_index=False).agg({'log':lambda x: list(x)})
Output:
id group log
0 10 UU1Q [23.0, 12.0]
1 10 UU2Q [15.0]
2 11 UU1Q [29.8, 33.0, 44.0]
3 11 UU2Q [17.0]
4 11 UU3Q [35.6]
5 13 UU2Q [17.77, 19.9, 55.0]
6 14 UU3Q [33.0]
7 15 UU3Q [22.0]
这很接近所需要的 - 添加了所有组合,如果每组创建一个元素具有相同值的元组:
from itertools import combinations
df = (df.groupby(['id','group'])['log']
.apply(lambda x: list(combinations(x, 2)) if len(x) > 1 else [(*x, *x)])
.explode()
.reset_index(name='comb'))
print (df)
id group comb
0 10 UU1Q (23.0, 12.0)
1 10 UU2Q (15.0, 15.0)
2 11 UU1Q (29.8, 33.0)
3 11 UU1Q (29.8, 44.0)
4 11 UU1Q (33.0, 44.0)
5 11 UU2Q (17.0, 17.0)
6 11 UU3Q (35.6, 35.6)
7 13 UU2Q (17.77, 19.9)
8 13 UU2Q (17.77, 55.0)
9 13 UU2Q (19.9, 55.0)
10 14 UU3Q (33.0, 33.0)
11 15 UU3Q (22.0, 22.0)
或者可以为每个 ['id','group'] 创建第一行的相同值元组并连接到由组合填充的 DataFrame df1
:
from itertools import combinations
df1 = (df.groupby(['id','group'])['log']
.apply(lambda x: list(combinations(x, 2)))
.explode()
.dropna()
.reset_index(name='comb'))
df2 = df.groupby(['id','group']).head(1).copy()
df2['comb'] = df2.pop('log').map(lambda x: (x,x))
df = pd.concat([df2, df1]).sort_values(['id','group'], ignore_index=True)
print (df)
id group comb
0 10 UU1Q (23.0, 23.0)
1 10 UU1Q (23.0, 12.0)
2 10 UU2Q (15.0, 15.0)
3 11 UU1Q (29.8, 29.8)
4 11 UU1Q (29.8, 33.0)
5 11 UU1Q (29.8, 44.0)
6 11 UU1Q (33.0, 44.0)
7 11 UU2Q (17.0, 17.0)
8 11 UU3Q (35.6, 35.6)
9 13 UU2Q (17.77, 17.77)
10 13 UU2Q (17.77, 19.9)
11 13 UU2Q (17.77, 55.0)
12 13 UU2Q (19.9, 55.0)
13 14 UU3Q (33.0, 33.0)
14 15 UU3Q (22.0, 22.0)