“名称”列在一行中包含一个人员名称,后跟他们需要执行的编号任务(带有简短描述),所有任务都与该人员名称相关联,直到出现另一个人员名称为止(因此,汤姆拥有以下所有任务他的名字与Tom关联,直到Jim出现为止,然后Jim与他名字之后的所有任务(直到下一个名字……等等)关联。所以这是我拥有的数据的示例:

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)。试图说出这样的话:在真值之间(可能是人的名字),通过对“三位数任务”进行分组来求和“天数”

最佳答案

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)


python - 根据条件在多个行中按/求和分组-LMLPHP



说明
使用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


使用cumsumName之后的每个连续行创建唯一编号

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


创建熊猫groupby对象
grps = df.groupby(grp_keys)

使用aggpd.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)


python - 根据条件在多个行中按/求和分组-LMLPHP

10-06 05:03