0

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

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

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

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

工人:如果在 DTDate/line_code 观察中工人的数量相等,那么工人的单个值将被带到折叠集。如果 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] 

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

4

1 回答 1

2

每个聚合函数(您传递给的函数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)。您会发现处理其中一些值是单个标量而其他值是列表的列很尴尬。

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

于 2013-10-06T05:45:58.850 回答