按月,年或日汇总值

时间:2013-08-16 20:45:19

标签: python numpy

例如,包含以下形式的子元素的列表:['mm,dd,yyyy,hh,mm''value']:

A = [
    ['09,02,2011,09,34' 'apple'],
    ['09,05,2011,10,20' 'juice'],
    ['06,04,2012,09,38' 'juice'],
    ['06,04,2012,09,38' 'juice'],
    ['06,04,2012,09,40' 'apple'],
    ['06,04,2012,09,40' 'juice'],
    ['06,04,2012,09,42' 'green'],
    ['06,04,2012,23,08' 'juice'],
    ['06,04,2012,23,10' 'juice'],
    ['06,04,2012,23,10' 'ferrari'],
    ['07,03,2012,20,12' 'juice'],
    ['07,07,2012,21,03' 'people'],
    ['07,07,2012,21,04' 'juice'],
    ['07,07,2012,21,04' 'people'],
    ['07,07,2012,21,04' 'lime'],
    ['08,16,2012,08,55' 'juice'],
    ['08,16,2012,08,55' 'juice'],
    ['08,16,2012,08,55' 'lime'],
    ['08,16,2012,08,55' 'lime'],
    ['08,16,2012,08,56' 'juice'],
    ['08,16,2012,08,57' 'juice'],
    ['08,16,2012,08,57' 'andy'],
    ['01,16,2013,03,20' 'people'],
    ['02,10,2013,04,59' 'lime']
    ]

我正在寻找一种可靠的聚合策略,允许使用月份(1-12)和年份(max_year到min_year)和每月天数(0-30)聚合值。更准确地说,对于列表子元素中的每个值:

所以,如果聚合类型是年份,那么:

    out = [
        {
        'name': 'value1_name',
        'series': [['min_year', 'count']...['max_year', 'count']] 
        },
        {
        'name': 'value2_name',
        'series':[['min_year', 'count']...['max_year', 'count']] 
        }, ...

        ]

如果聚合类型是月份,则:

    out = [
        {
        'name': 'value1_name',
        'series': [['01', 'count']...['12', 'count']] 
        },
        {
        'name': 'value2_name',
        'series':[['02', 'count']...['12', 'count']] 
        }, ...

        ]

如果聚合类型以天的形式提供,那么:

    out = [
        {
        'name': 'value1_name',
        'series': [['01', 'count']...['30', 'count']] 
        },
        {
        'name': 'value2_name',
        'series':[['01', 'count']...['30', 'count']] 
        }, ...

        ]

对我来说,这个问题的全部痛点是填写缺少各个聚合类型的月,日或年值。因此,例如,如果聚合类型是年份,并且我正在聚合所有'果汁'值,那么:

    out = [
        {
        'name': 'juice',
        'series': [['2011', '1'],['2012', '11'],['2013', '0']] 
        },..

同样是月份和日期值的问题。关键是所有的值('apple','juice'等)应该有相同长度的系列,这意味着如果2011年和2013年不存在'ferrari'那么它的系列应该有['2011' ,'0']和['2013','0']。同样,如果除了六月('06')之外的任何月份都不存在'法拉利',那么它的系列应该是:

  'series': [
['01', '0'],
['02', '0'],
['03', '0'],
['04', '0'],
['05', '0'],
['06', '1'],
['07', '0'],
['08', '0'],
['09', '0'],
['10', '0'],
['11', '0'],
['12', '0']
 ]

..天也一样..

我可以拥有的最佳策略是什么?非常感谢。

1 个答案:

答案 0 :(得分:1)

所以如果你想要一个使用Numpy的解决方案,这里有一个紧凑的代码:

# col is the column of your data to aggregate over
# minval and maxval are the minimum and maximum (inclusive)
# values they can take. Getting these to set automatically
# is a trivial task.
def agg(A, col, minval, maxval):
    D = np.array( [ [ int(x) for x in d.split(',') ] for d,t in A ] )
    V = np.array( [ t for d,t in A ] )
    dvals = range(minval,maxval+1)
    q = []
    for v in unique(V):
        q.append( { 'name': v, 'series': 
                 numpy.array([ [x,sum(V[D[...,col]==x]==v)] for x in dvals ]) } )
    return q

基本上,这会将您的数据转换为numpy数组,这使您可以使用高级索引来轻松聚合数据。 D包含日期,V值,因此,例如,V [D [...,1] == 2]为您提供每天有一天(第1列)为2的值。

请注意,这个版本不一定是禁食。特别是,对于大型数据集,转换为numpy数组可能有点慢,并且迭代潜在值的方法非常紧凑,但不一定是最快的方法。对于前者,您可以创建空数组并使用您的数据填充它们,或者以更适合fromstring或loadtxt的方式获取数据。对于后者,我不太确定最佳算法是什么。