“名称”列包含一行中的人名,后面是他们需要执行的编号任务(带有小描述),所有任务都与该人名相关联,直到出现另一个人名(所以汤姆全部他的名字下面的任务与汤姆相关,直到吉姆出现,然后吉姆与他的名字之后的所有任务相关联,直到下一个名字......等等)。以下是我的数据示例:
Name Three Digit Task Number of Days
Tom BLANK 0.00
1.1.6.1 Task Description 1.1.6 9.00
1.1.6.2 Task Description 1.1.6 8.25
1.1.1.4 Task Description 1.1.1 13.25
Jim BLANK 0.00
1.1.3.1 Task Description 1.1.3 8.75
1.2.1.1 Task Description 1.2.1 6.00
1.2.1.2 Task Description 1.2.1 12.75
所以我想得到每个人的天数总和,按三位数任务分组。希望它看起来像这样:
Tom 1.1.1 13.25
Tom 1.1.6 17.25
Jim 1.1.3 8.75
Jim 1.2.1 18.75
所以我尝试过使用:
import string
ALPHA = string.ascii_letters
df['Name'].str.startswith(tuple(ALPHA))
如果“名称”列以字母开头,则返回true / false(字母为True,否则为false)。试图说出这样的话:在真实(这将是人民的名字)之间通过分组'三位数任务'来总结'天数'
答案 0 :(得分:1)
<强> TL;博士
name_bool = df.Name.str.match('^[a-zA-Z]')
grp_keys = name_bool.cumsum()
grps = df.groupby(grp_keys)
tdt = 'Three Digit Task'
nod = 'Number of Days'
funcs = {'Name': 'first', nod: 'sum'}
dicts = {g.iloc[0, 0]: g.tail(-1).groupby(tdt).agg(funcs) for _, g in grps}
pd.concat(dicts)
<强> 解释 强>
使用regex
查找哪些行的Name
列以字母开头。
name_bool = df.Name.str.match('^[a-zA-Z]')
name_bool
0 True
1 False
2 False
3 False
4 True
5 False
6 False
7 False
Name: Name, dtype: bool
使用cumsum
为Name
grp_keys = name_bool.cumsum()
grp_keys
0 1
1 1
2 1
3 1
4 2
5 2
6 2
7 2
Name: Name, dtype: int64
创建pandas groupby
对象
grps = df.groupby(grp_keys)
使用agg
和pd.concat
创建最终pd.DataFrame
funcs = {'Name': 'first', nod: 'sum'}
dicts = {g.iloc[0, 0]: g.tail(-1).groupby(tdt).agg(funcs) for _, g in grps}
pd.concat(dicts)