如何通过未排序的列表对数据框架进行分组?



我有一个更大的数据集,它的结构与这个数据框类似(包括[]):

Day  Worker_ID Skills Team_members
0    1          1  [1 3]        [1 3]
1    1          2  [2 5]        [4 2]
2    1          3  [4 2]        [3 1]
3    1          4  [3 3]        [2 4]
4    2          1  [2 4]        [1 3]
5    2          2  [3 5]        [4 2]
6    2          3  [4 3]        [3 1]
7    2          4  [2 2]        [2 4]

我想把我的数据框按工作人员的团队分组,所以它看起来像这样([]是可选的):

Day  Team_ID Team_Skills Team_members
0    1       1  [2.5 2.5]        [1 3]
1    1       2    [2.5 4]        [2 4]
2    2       1    [3 3.5]        [1 3]
3    2       2  [2.5 3.5]        [2 4]

我假设这个过程是这样的:

  1. 创建原始数据帧的.copy()
  2. 对team_members-column中的向量进行排序
  3. 小组成员列& &;日列
  4. 删除Worker_ID列
  5. 创建一个新的team_id列,以便每次引入新的team_members组合时,分配一个新的团队编号
  6. 计算每个团队在特定日期的技能平均值,并重新命名列

下面是代码,如果你想尝试一下:

import pandas as pd
data = {'Day': [1, 1, 1, 1, 2, 2, 2, 2],
'Worker_ID': [1, 2, 3, 4, 1, 2, 3, 4],
'Skills': ['[1 3]', '[2 5]', '[4 2]', '[3 3]', '[2 4]', '[3 5]', '[4 3]', '[2 2]'],
'Team_members': ['[1 3]', '[4 2]', '[3 1]', '[2 4]', '[1 3]', '[4 2]', '[3 1]', '[2 4]']}
df = pd.DataFrame(data)

这是一种方法。首先,将团队成员字符串转换为列表,然后"删除订单"。将它们转换为frozenset(基本上是不可变的集合)。

>>> labels = df['Team_members'].str.findall("d").map(frozenset) 
>>> labels 
0    (1, 3)
1    (2, 4)
2    (1, 3)
3    (2, 4)
4    (1, 3)
5    (2, 4)
6    (1, 3)
7    (2, 4)

然后将数据按天分组,然后按之前的标签分组,计算每个团队的平均技能


def skills_mean(group_skills):
# worker skills matrix 
group_skills = group_skills.str.findall("d").tolist()
# compute the mean along the columns
mean_skills = np.asarray(group_skills, dtype=int).mean(0)
return str(mean_skills)
>>> res = (
df.groupby(["Day", labels], as_index=False)
.agg({"Team_members": "min", 
"Skills": skills_mean})
) 
>>> res
Day Team_members     Skills
0    1        [1 3]  [2.5 2.5]
1    1        [2 4]  [2.5 4. ]
2    2        [1 3]  [3.  3.5]
3    2        [2 4]  [2.5 3.5]

最后,添加'Team_ID'列

>>> res['Team_ID'] = res.groupby("Team_members").ngroup().add(1)
>>> res
Day Team_members     Skills  Team_ID
0    1        [1 3]  [2.5 2.5]        1
1    1        [2 4]  [2.5 4. ]        2
2    2        [1 3]  [3.  3.5]        1
3    2        [2 4]  [2.5 3.5]        2

这是您的问题的一般逻辑。我不会给你确切的格式,因为我在我的手机上,但这应该给你一个很好的起点。

import numpy as np
df2 = (df.assign(TS=df['Skills'].str[1:-1].str.split())
.explode('TS')
.assign(TS=lambda d: d['TS'].astype(float))
)
group = df2['Team_members'].apply(lambda r: tuple(set(r[1:-1].split())))
(df2.groupby(['Day', np.tile([0,1], len(df)), group])['TS'].mean()         
.groupby(level=['Day', 'Team_members']).apply(list)
.reset_index()
)

输出:

Day Team_members          TS
0    1       (1, 3)  [2.5, 2.5]
1    1       (4, 2)  [2.5, 4.0]
2    2       (1, 3)  [3.0, 3.5]
3    2       (4, 2)  [2.5, 3.5]

相关内容

  • 没有找到相关文章

最新更新