загрузка объекта groupby в pandas

У меня есть несколько временных рядов с наблюдениями в виде строк (индексированных меткой времени, n> 5000) и переменными в виде столбцов (n = 419). Я выбираю N процент включения в временные ряды, а затем вызываю groupby для группировки по годам. Мне нужно среднее значение, стандартное отклонение, а затем 95% доверительные интервалы для каждого года. Я могу достаточно легко получить среднее значение и стандартное значение с помощью приведенного ниже кода, но мне нужно вызвать отдельную функцию начальной загрузки, чтобы получить 95% CI для каждого года и каждой группы:

Это краткий обзор того, как выглядят сгруппированные данные: (есть 86 строк для 2013 года и 28 столбцов, а данные начинаются с 1970-х годов). Мне нужно использовать «бутсрап» для каждого столбца в группе для каждого года в группе.

for year, group in grouped:
print year
print group

2013
                  101        102        103        104       105        109     
2013-04-02    3162.84    4136.02   77124.56       0.00    973.18    9731.81   
2013-04-04    1033.81    5464.44   87283.30    3692.19   4282.94     295.37   
2013-04-04     640.75    4164.87  131033.14    2563.00   1121.31     961.12   
2013-04-10     246.87    4196.84   88380.57    4443.72    493.75    1234.37   
2013-04-13       0.00    8300.49  114291.42   10003.16    212.83    6385.00   

` А вот мои функции для groupby и bootstrap:

def gbY_20pct(nm): # sort into 20% timeseries inclusion, groupby year, take mean for year
        nm1=nm.replace('0', np.nan) # remove 0 for logical count
        coun=nm1.count(axis=0,numeric_only=True)
        pct=(coun/len(nm1)) *100
        pCount=pct.loc[pct >= 20]
        nm1=nm.loc[:, pCount.index]
        grouped = nm1.groupby(nm1.index.map(lambda x: x.year))
        yrly=grouped.mean().astype(int)
        yrly_coun=grouped.count().astype(int)
        yrly_std=grouped.std().astype(int)
        yrly_max=grouped.max().astype(int)
        yrM1=yrly.join(yrly_std, lsuffix=' mean', rsuffix=' std', how='outer')
        yrM2=yrly_max.join(yrly_coun, lsuffix=' max', rsuffix=' count', how='outer')
        data=yrM1.join(yrM2, how='outer')
        return data

`

import numpy as np
import numpy.random as npr  
def bootstrap(data, num_samples, statistic, alpha):
    """Returns bootstrap estimate of 100.0*(1-alpha) CI for statistic."""
    n = len(data)
    idx = npr.randint(0, n, (num_samples, n))
    samples = data[idx]
    stat = np.sort(statistic(samples, 1))
    return (stat[int((alpha/2.0)*num_samples)],
            stat[int((1-alpha/2.0)*num_samples)])

Чтобы проверить код, я вызываю его вручную (сгруппировано и функция не закрыта)

from bootstrap import bootstrap
low, high = bootstrap(grouped, 100000, np.mean, 0.05)
Traceback (most recent call last):

  File "<ipython-input-49-cd362c7908d1>", line 1, in <module>
    low, high = bootstrap(grouped, 100000, np.mean, 0.05)

  File "bootstrap.py", line 14, in bootstrap

  File "C:\Users\ryan.morse\AppData\Local\Continuum\Anaconda\lib\site-packages\pandas\core\groupby.py", line 2991, in __getitem__
    bad_keys = list(set(key).difference(self.obj.columns))

TypeError: unhashable type: 'numpy.ndarray'

Проблема исходит из строки samples = data[idx]. Я подозреваю, что мне нужно быть более конкретным, чем использовать «сгруппировано» для поля данных в начальной загрузке, но я не уверен, как это сделать. Нужно ли мне применять это как лямбда-функцию? Или, может быть, с циклом for? Любые предложения будут высоко ценится.

Посмотрев на эту страницу: Pandas, вычислите многие средства с помощью доверительные интервалы начальной загрузки для построения графика и использования функции начальной загрузки scikit https://scikits.appspot.com/bootstrap, я протестировал функцию, определенную выше, и обнаружил, что она НАМНОГО быстрее с сопоставимыми результатами.


Редактировать:

Я думаю, что что-то вроде этого может работать, но я все еще не могу правильно понять синтаксис:

groups=dict(list(grouped)) # this allows me to visualize the data and call values

for key, value in groups.iteritems():
low_i, high_i = bootstrap(groups.values(), 100000, np.mean, 0.05) 

Traceback (most recent call last):

  File "<ipython-input-36-7a8e261d656e>", line 2, in <module>
    low_i, high_i=bootstrap(groups.values(), 10000, np.mean, 0.05)

  File "<ipython-input-15-3ce4acd651dc>", line 7, in bootstrap
    samples = data[idx]

TypeError: only integer arrays with one element can be converted to an index

Я не уверен, как вызывать «данные» для функции начальной загрузки, а также как перебирать все годы и поддерживать низкие и высокие значения для всех лет (либо в одном фрейме данных, либо в двух отдельных).

Любая помощь будет принята с благодарностью...


РЕДАКТИРОВАТЬ 2 Я могу так же легко использовать лямбда-функцию, однако я не могу получить правильный результат:

for col, group in nm1.groupby(nm1.index.year):
    lo,hi=bootstrap(group,1000, np.mean, 0.05)

lo
Out[117]: 
array([ 0.05713616,  0.30724739,  0.39592714,  0.55113183,  0.68623155,
        0.69493923,  0.73513661,  0.84086099,  0.85882618,  0.86698939,
        0.99399694,  1.04415927,  1.06553914,  1.11306698,  1.15344871,
        1.27943327,  1.43275895,  1.81076036,  2.21647657,  2.37724615,
        2.39004626,  2.43154256,  2.89940325,  3.02234954,  3.30773642,
        3.96535146,  3.98973744,  4.38873853])

hi
Out[118]: 
array([ 0.20584822,  0.38832222,  0.42140066,  0.48615202,  0.59686031,
        0.67388397,  0.84269082,  0.84532503,  0.87078368,  0.9033272 ,
        0.90765817,  0.97523759,  0.99186096,  1.01668772,  1.06681722,
        1.18205259,  1.38524423,  1.79908484,  2.22314773,  2.33789105,
        2.5521743 ,  2.64242269,  2.88851233,  2.94387756,  3.44294791,
        3.63914938,  3.99185026,  4.36450246])

Если бы это сработало, у меня было бы привет и привет для каждого из 28 столбцов для каждого из 33 лет, вместо этого у меня есть упорядоченный массив чисел, которые, кажется, не имеют никакого реального значения... это фрагмент yrly который содержит логарифмическое преобразование групповых значений для каждого года, загруженные ЭК должны быть близки к этим числам, в отличие от приведенных выше массивов.

           101       102       103       104       105       109       135  
1978  3.416638  3.701268  3.828442  2.911944  2.687491  2.076515  1.232035   
1979  2.710939  3.172061  4.234109  1.666818  3.390646  1.355179  3.003813   
1980  2.652617  2.375495  3.316380  1.101594  2.220028  1.195449  1.998862   
1981  3.363424  3.485015  3.441784  2.242618  2.256745  1.719140  1.150454   
1982  2.791865  2.019883  4.093960  1.038226  2.106627  1.180935  2.456144   
1983  2.597307  2.213450  4.458691  1.274352  2.820910  1.705242  3.452762   
1984  3.042197  4.023952  3.816964  2.499883  2.445258  1.769485  1.690180   
1985  2.669850  2.162608  3.600731  1.400102  1.845218  1.234235  2.517108   
1986  3.597527  2.763436  2.790792  1.410343  2.116275  1.042812  1.528532

person Ryan    schedule 17.10.2014    source источник


Ответы (1)


После всего этого я пришел к следующему ответу:

import scipy.stats
ci = grouped.aggregate(lambda x: scipy.stats.sem(x, ddof=1) * 1.96) #use mean +(-) ci to get 95% conf interval

Оказывается, мне на самом деле не нужно загружать данные, поэтому я могу просто оценить 95% доверительный интервал на основе стандартной ошибки среднего, умноженной на 0,975 квантиль нормального распределения, предполагая, что данные нормально распределены (но это другой вопрос...).

           101       102       103       104       105       109       135
1978  0.230630  0.191651  0.168648  0.282588  0.237939  0.288924  0.257476   
1979  0.192579  0.147305  0.120740  0.225826  0.145646  0.266530  0.199315   
1980  0.189258  0.195263  0.182756  0.166479  0.166401  0.172550  0.189483   
1981  0.200727  0.169663  0.184478  0.232392  0.198591  0.230457  0.194084   
1982  0.271740  0.267881  0.164450  0.248718  0.246636  0.260973  0.253430   
1983  0.253495  0.279114  0.116744  0.266888  0.236672  0.317195  0.155766   
person Ryan    schedule 23.10.2014