【问题标题】:Collapsing Data using GroupBy Pandas使用 GroupBy Pandas 折叠数据
【发布时间】:2013-10-06 05:32:27
【问题描述】:

我有一个表示时间序列数据的 pandas 数据框。我有一个名为 DTDate 的列(这是一个日期时间日期)和一个名为 line_code 的列(它是观察单位 - 它恰好是工厂的生产线)。我有很多列数据,但为了这个问题,让我们假设只有三个:

workers - 生产线上的工人数量。 item - 生产线上正在生产的项目的名称。 output - 生产线上项目的输出量。

有时每行只生产一个项目,有时是多个项目。因此,有时每个 DTDate/line_code 有一个观察结果,有时有多个观察结果。我需要将数据集折叠为每个 DTDate/line_code 的单个观察值。

问题来了——我们还不知道如何聚合数据,因此目前我只需要实现一个可以尝试多种聚合方法的结构。 当该行仅产生一项时,我只需要按原样保留数据行。当该行在给定的 DTDate 上产生多个项目时,我想根据以下内容将观察结果折叠为单个观察结果:

workers:如果在 DTDate/line_code 观察中workers 的数量相等,那么workers 的单个值被传送到折叠集。如果 os 工作人员的数量不相等,则创建一个列表对象,其中包含 DTDate/line_code 观察中工作人员的所有值。 项目:项目的列表对象被结转到折叠集合。 输出:输出的列表对象被结转到折叠集。

通过在折叠集中列出项目,我使结构足够灵活,以便我可以在收到指示时为每一列尝试不同的聚合方法。

到目前为止,我将数据分组如下:

import pandas as pd
import numpy as np
from pandas import DataFrame
DF = DataFrame(mydata, columns = ['DTDate', 'line_code', \
                                  'workers', 'item', 'output'])

DFGrouped = DF.groupby(['DTDate', 'line_code'])

现在我意识到我想要做的是:

DFAggregated = DFGrouped.agg({'DTDate': max(), 'line_code' : max(), \
                              'workers' : myfunc1, 'item' : myfunc2, \
                              'output' : myfunc2})

在哪里: myfunc1 评估指定列的组中的所有值是否相等,如果相等则返回单个值,否则返回每个值的列表。

myfunc2 返回指定列中组中所有值的列表。

我的问题是我不知道如何编写这些函数,主要是因为我不清楚如何迭代组特定的索引/行。我已经阅读了有关 grouby 等的 python 文档,但发现它不是很有用。我意识到我应该发布更多我尝试过的代码,但我发现甚至很难在这里起步。任何指针将不胜感激。

(现在扩展给出说明性功能代码)

顺便说一句,我希望 myfunc1 和 myfunc2 看起来像这样:

def myfunc1(ColName):
    if len(set([DFGroup[ColName][x] for x in DFGroup.index])) == 1:
        return DFGroup[ColName].max()
    else:
            return [DFGroup[ColName][x] for x in DFGroup.index]

def myfunc2(ColName):
    return [DFGroup[ColName][x] for x in DFGroup.index] 

如您所见,我不确定如何引用组索引等。

【问题讨论】:

    标签: python python-2.7 pandas dataframe aggregate


    【解决方案1】:

    每个聚合函数(您传递给agg 的函数)作为一个系列传递给它聚合的列。所以你的myfunc2 就是lambda x: list(x.unique())。您的 myfunc1 将是:

    def collapse(x):
        uniq = x.unique()
        if len(uniq) == 1:
            return uniq[0]
        else:
            return list(uniq)
    

    但是,您可能会发现处理结果有些尴尬。至少,我认为您可能只想始终返回一个列表(也就是说,忘记myfunc1 并始终使用myfunc2)。您会发现处理其中一些值是单个标量而其他值是列表的列很尴尬。

    此外,您可能还想使用apply,它可以让您返回整个DataFrame。通过这种方式,您实际上可以返回一个新的分组表,而不是将项目折叠到一个列表中,其中源列中的每个唯一值对应一行。

    【讨论】:

    • 参数x在哪里是DF的列?谢谢,这很有帮助。看来我不需要实际迭代每个组中的索引。如果有必要,人们将如何做到这一点? Apply 似乎也很有用,而且似乎以几乎相同的方式工作。我现在看看。非常感谢。
    • @WoodyPride:正如我所说,函数的参数(在我的示例中为x)是一个包含列数据的熊猫系列。您可以像使用任何系列一样对其进行迭代或对其执行任何操作。
    猜你喜欢
    • 2020-03-20
    • 2017-09-16
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多