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'的字符串。如果它包含布尔值TrueFalse,你只需取出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

注意:我从您的描述中了解到,单行组也被视为连续行组。因此,如果其endFlowFalse,则计数将包括它

【讨论】:

太棒了!那行得通!但是,我现在有另一个要求,我必须执行此操作并仅针对“useCaseId”列表进行分组。我怎样才能做到这一点?我的意思是说,我不想将上述数据框与“useCaseId”列中存在的所有 useCaseId 分组,但我想将它与我拥有的 useCaseId 列表分组,这可能吗? @TonyMathew:有可能。但是,请提出一个新问题,并提供有关新要求、输入和所需输出的详细信息,就像您在此问题中所做的那样。您还可以包含返回此问题的链接。样本和期望的输出价值超过一千字。在这个问题中,如果没有您更新 df.head(),我有点迷茫。

以上是关于Python-循环遍历pandas Groupby对象的主要内容,如果未能解决你的问题,请参考以下文章

在数据帧上的 pandas groupby 之后循环遍历组

python--pandas分组聚合

Python / Pandas:循环遍历数字列表

循环遍历 Pandas 数据框以填充列表(Python)

Python 3 函数循环遍历 pandas 数据框以更改模式

Python Pandas DF Pivot 和 Groupby