我有一个表示时间序列数据的pandas数据框。我有一个名为DTDate的列(它是一个日期时间日期)和一个名为line_code的列(它是观察的单位 - 它恰好是工厂中的生产线)。我有很多数据列,但为了这个问题,让我们想象只有三个:
工人 - 生产线上的工人数量。 item - 生产线上生产的料品名称。 输出 - 生产线上项目的输出量。
有些日子,每一行只生成一个项目,有时是多个项目。因此,有时每个DTDate / line_code有一个观察值,有时会有多个观察值。我需要根据DTDate / line_code将数据集折叠为单个观察。
这就是问题 - 我们还不知道我们想要如何聚合数据,因此目前我只需要实现一个可以尝试多种聚合方法的结构。 当该行只生成一个项目时,我只需要保留数据行。当该行在给定的DTDate上生成多个项目时,我想根据以下内容将观察结果折叠为单个观察:
工作人员:如果在DTDate / line_code观察中工人数量相等,则单个工作人员值将进入折叠集合。如果os worker数量不相等,则创建一个列表对象,其中包含DTDate / line_code观察中的所有worker值。 item:项目的列表对象被转发到折叠集合。 output:输出的列表对象被转发到折叠集。
通过在折叠集中包含列表项,我将保留足够的灵活性以允许自己在每个列的实验中使用不同的聚合方法。
sofar我将数据分组如下:
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返回指定列中组中所有值的列表。
我的问题是我没有idead如何编写这些函数,主要是因为我不清楚如何遍历特定于组的索引/行。我已经阅读了关于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]
你可以看到我不知道如何引用群组索引等。
答案 0 :(得分:2)
每个聚合函数(传递给agg
的函数)作为一个Series传递给它聚合的列。因此,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。通过这种方式,您可以实际返回一个新的分组表,而不是将项目折叠到列表中,为源列中的每个唯一值返回一行。