Python-循环遍历pandas Groupby对象
Posted
技术标签:
【中文标题】Python-循环遍历pandas Groupby对象【英文标题】:Python- Looping through pandas Groupby object 【发布时间】:2019-10-18 02:29:21 【问题描述】:这是我的数据框中的示例行:
"sessionId" : "454ec8b8-7f00-40b2-901c-724c5d9f5a91",
"useCaseId" : "3652b5d7-55b8-4bee-82b6-ab32d5543352",
"timestamp" : "1559403699899",
"endFlow" : "true"
我通过'sessionId'进行分组,这会给我一个这样的组:
Row 1:
"sessionId" : "454ec8b8-7f00-40b2-901c-724c5d9f5a91",
"useCaseId" : "usecaseId1",
"timestamp" : "1559403699899",
"endFlow" : "false"
,
Row 2:
"sessionId" : "454ec8b8-7f00-40b2-901c-724c5d9f5a91",
"useCaseId" : "usecaseId1",
"timestamp" : "1559403699899",
"endFlow" : "false"
,
Row 3:
"sessionId" : "454ec8b8-7f00-40b2-901c-724c5d9f5a91",
"useCaseId" : "usecaseId2",
"timestamp" : "1559403699899",
"endFlow" : "true"
,
Row 4:
"sessionId" : "454ec8b8-7f00-40b2-901c-724c5d9f5a91",
"useCaseId" : "usecaseId1",
"timestamp" : "1559403699899",
"endFlow" : "false"
,
Row 5:
"sessionId" : "454ec8b8-7f00-40b2-901c-724c5d9f5a91",
"useCaseId" : "usecaseId1",
"timestamp" : "1559403699899",
"endFlow" : "true"
以上面的组为例,我想在这里实现的是,在按“sessionId”对数据框进行分组后,我想循环遍历具有相同“useCaseId”的连续行(所以从上面的组中,会有我要循环的三组连续行,Row1-Row2,Row3,Row4-Row5)
从上述每组连续的行中(Row1-Row2,Row3,Row4-Row5(每组具有相同的useCaseId),我想找到只有 false 的行 endflow 值的集合数。
因此,从上面给出的组示例来看,预期结果如下:1(因为,具有相同 useCaseId 'usecaseId1' 的 Row1-Row2 的 endflow 只有 'false',而 'Row3'并且 'Row4-Row5' 有 endflow 'true')
我怎样才能做到这一点?更新:
df.head():
sessionId useCaseId timestamp endFlow
0 sessionId1 useCaseId1 1559403699899 false
1 sessionId1 useCaseId1 1559403699899 false
2 sessionId1 useCaseId2 1559403699899 true
3 sessionId1 useCaseId1 1559403699899 false
4 sessionId1 useCaseId1 1559403699899 true
我尝试了什么: 我已经尝试按'sessionId'和'usecaseId'对数据框进行分组,但这不起作用,因为它会使用'usecaseId'唯一地对数据框进行分组,这不是我想要的,我想在按'分组后循环连续行sessionId' 具有相同的 'usecaseId',然后将具有相同 'useCaseId' 且只有 'endFlow' 的连续行计数为 'false'。
预期输出: 按 'sessionId' 分组后,我想从上面给出的组示例中计算具有相同 'useCaseId' 且具有 'endFlow' 的连续行数仅为 'false',预期结果如下: 1(由于相同useCaseId 'usecaseId1'的Row1-Row2的endflow只有'false',而'Row3'和'Row4-Row5'的endflow为'true')
【问题讨论】:
请编辑您的帖子以包含以下信息:1)df.head()
-- 请edit 您对这些数据提出问题,复制粘贴要容易得多。 2) 包括您运行的任何代码以及它为什么不起作用,以及 3) 请为给定的数据样本添加您的预期输出。
@cs95 我更新了我的问题,你能看看吗? :) 这对我来说很重要,我真的需要你的帮助......
我想你在找(~(df['endFlow'] == "true").groupby([df['sessionId'], df['useCaseId'].ne(df['useCaseId'].shift()).cumsum()]).max()).sum()
@cs95,成功了!安迪的以下回答也有效。但是,我现在有另一个要求,我必须执行此操作并仅针对“useCaseId”列表进行分组。我怎样才能做到这一点?我的意思是说,我不想将上述数据框与“useCaseId”列中存在的所有 useCaseId 分组,但我想将它与我拥有的 useCaseId 列表分组,这可能吗?
【参考方案1】:
你可以试试这个:(我假设df.endFlow
包含'true'
和'false'
的字符串。如果它包含布尔值True
和False
,你只需取出replace
命令.)
df.endFlow.replace('true': True, 'false': False).groupby([df.sessionId, df.useCaseId.ne(df.useCaseId.shift()).cumsum()]).sum().eq(False).sum()
Out[1258]: 1
现在,我将您的样本更改为包括满足条件的 2 组,它还正确报告计数如下:
df1:
sessionId useCaseId timestamp endFlow
0 sessionId1 useCaseId1 1559403699899 false
1 sessionId1 useCaseId1 1559403699899 false
2 sessionId1 useCaseId2 1559403699899 true
3 sessionId1 useCaseId1 1559403699899 false
4 sessionId1 useCaseId1 1559403699899 false
df1.endFlow.replace('true': True, 'false': False).groupby([df1.sessionId, df1.useCaseId.ne(df1.useCaseId.shift()).cumsum()]).sum().eq(False).sum()
Out[1264]: 2
注意:我从您的描述中了解到,单行组也被视为连续行组。因此,如果其endFlow
为False
,则计数将包括它
【讨论】:
太棒了!那行得通!但是,我现在有另一个要求,我必须执行此操作并仅针对“useCaseId”列表进行分组。我怎样才能做到这一点?我的意思是说,我不想将上述数据框与“useCaseId”列中存在的所有 useCaseId 分组,但我想将它与我拥有的 useCaseId 列表分组,这可能吗? @TonyMathew:有可能。但是,请提出一个新问题,并提供有关新要求、输入和所需输出的详细信息,就像您在此问题中所做的那样。您还可以包含返回此问题的链接。样本和期望的输出价值超过一千字。在这个问题中,如果没有您更新df.head()
,我有点迷茫。以上是关于Python-循环遍历pandas Groupby对象的主要内容,如果未能解决你的问题,请参考以下文章