Python 使用GroupBy折叠数据

Python 使用GroupBy折叠数据,python,python-2.7,pandas,dataframe,aggregate,Python,Python 2.7,Pandas,Dataframe,Aggregate,我有一个表示时间序列数据的数据框。我有一个名为DTDate的列(这是一个日期时间日期)和一个名为line_code的列(这是观察的单位-它恰好是工厂中的一条生产线)。我有很多列数据,但是为了这个问题,让我们假设只有三列: 工人-生产线上的工人数量。 项目-生产线上正在生产的项目的名称。 输出-生产线上项目的输出量 有时每行只生成一个项目,有时生成多个项目。因此,有时每个DTDate/line_代码有一个观测值,有时有多个观测值。我需要根据DTDate/line\u代码将数据集折叠成一个观察值 这

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

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

有时每行只生成一个项目,有时生成多个项目。因此,有时每个DTDate/line_代码有一个观测值,有时有多个观测值。我需要根据DTDate/line\u代码将数据集折叠成一个观察值

这里是难点-我们还不知道我们想要如何聚合数据,因此,目前我只需要实现一个可以尝试多种聚合方法的结构。 当该行只生成一个项时,我只需要保持数据行的原样。当该行在给定的DTDate上生成多个项目时,我希望根据以下内容将观察值折叠为单个观察值:

DFAggregated = DFGrouped.agg({'DTDate': max(), 'line_code' : max(), \
                              'workers' : myfunc1, 'item' : myfunc2, \
                              'output' : myfunc2})
workers:如果在DTDate/line_代码观察值内Worker数相等,则单个Worker值将被带到折叠集。如果操作系统工作者的数量不相等,则创建一个列表对象,其中包含DTDate/line_代码观察值中工作者的所有值。 项目:项目的列表对象将结转到折叠集。 输出:输出的列表对象将结转到折叠集

通过将列表项放在折叠集中,我使结构具有足够的灵活性,允许自己在接到指示时为每个列尝试不同的聚合方法

迄今为止,我已将数据分组如下:

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] 
正如您所见,我不确定如何引用组索引等。

每个聚合函数(传递给
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
,它允许您返回整个数据帧。通过这种方式,您可以实际返回一个新的分组表,其中源列中每个唯一值对应一行,而不是将项目折叠到列表中。

其中参数x是DF中的列?谢谢,这很有帮助。似乎我不需要在每个组中迭代索引。如果有必要,人们会怎么做?Apply看起来也很有用,而且它的工作方式也差不多。我现在去看看。非常感谢。@WoodyPride:正如我所说,函数的参数(
x
,在我的示例中)是一个包含列数据的pandas系列。您可以对它进行迭代,也可以对它执行任何操作,就像对任何序列一样。