我有一个数据集,需要在单个字段上进行分组并在多个字段上进行汇总。作为聚合的一部分,我需要有条件地按排序顺序连接字符串列值。
输入:
SYSTIME TT REC TABLE cat_a cat_b cat_c
01/11/2019 00:00 2 102 A 1 0 0
01/11/2019 00:00 2 103 B 1 0 0
01/11/2019 00:00 2 150 C 0 1 0
01/11/2019 00:01 3 200 B 1 0 0
01/11/2019 00:01 3 150 A 1 0 0
01/11/2019 00:01 3 104 D 0 0 1
01/11/2019 00:02 4 200 F 1 0 0
01/11/2019 00:02 5 250 A 1 0 0
01/11/2019 00:02 2 120 C 0 1 0
01/11/2019 00:02 3 150 E 1 0 0
预期输出:
SYSTIME TT REC TABLE cat_a cat_b cat_c
01/11/2019 00:00 2 355 A;B 2 1 0
01/11/2019 00:01 3 454 A;B 2 0 1
01/11/2019 00:02 5 520 A;E;F 3 1 0
我有以下代码:
df_table_acc=df.groupby(['SYSTIME'],as_index=False).agg({'TT' : 'max','REC' : 'sum','TABLE': ';'.join, 'cat_a': 'sum', 'cat_b': 'sum', 'cat_c': 'sum'})
问题在于字符串连接,我想将cat_a = 1的TABLE值也连接在一起,还要排序。 目前,我在00:00分钟收到A; B; C,但只希望cat; a = 1
的A; B是否可以向联接函数添加条件?
P.S:我是python的新手,我确实看到了类似的问题,但是我想专门在agg函数中添加条件
答案 0 :(得分:1)
我找不到在agg
中执行此操作的方法,因此,如果有人愿意请说。
不过,它很容易在agg
之外使用,
df_table_acc=df.groupby(['SYSTIME'],as_index=False).agg( #Remove TABLE from first agg
{'TT' : 'max','REC' : 'sum', 'cat_a': 'sum', 'cat_b': 'sum', 'cat_c': 'sum'})
df_table_acc = pd.merge(df_table_acc, df[df['cat_a']>0].copy().groupby(['SYSTIME'],as_index=False).agg(
{'TABLE':';'.join}),how='left',on='SYSTIME')
已针对索引问题进行了编辑。现在,我们在merge
上使用SYSTIME
以确保TABLE
与SYSTIME
或者,通过更改数据,之后进行一些清理(编辑:修复了这一部分并增加了更好的分离)
import re
df['TABLE'] = df.apply(lambda x: x['TABLE'] if x['cat_a']>0 else '', axis=1)
df_table_acc=df.groupby(['SYSTIME'],as_index=False).agg(
{'TT' : 'max','REC' : 'sum','TABLE': ';'.join,
'cat_a': 'sum', 'cat_b': 'sum', 'cat_c': 'sum'})
df_table_acc.TABLE = df_table_acc.TABLE.apply(lambda x: re.sub(';+',';',x).strip(';'))
#Quick explanation: the re part avoids having repeat ";" eg: "A;;C;D;;G" -> "A;C;D;G"
#The strip removes outside strings eg: ";A;B;" -> "A;B"
在使用第二种方法之前,请确保不需要其他任何TABLE
列,或者使用诸如TABLE2
之类的虚拟列。
答案 1 :(得分:0)
可以通过在应用groupby和agg之前过滤数据来解决您的问题
function。只需在使用此代码之前添加df=df[df['cat_a']==1].sort_values('TABLE')
df_table_acc = df.groupby(['SYSTIME'],as_index = False).agg({'TT':'max','REC':'sum','TABLE':';'。join,' cat_a':'sum','cat_b':'sum','cat_c':'sum'})