Начальная загрузка группового объекта в пандах
У меня есть несколько временных рядов с наблюдениями в виде строк (проиндексированных по временной метке, n > 5000) и переменных в виде столбцов (n=419). Я выбираю N процентов для включения во временные ряды, а затем вызываю группу по группам по годам. То, что я хочу, это среднее значение, стандартное отклонение, а затем 95% доверительные интервалы для каждого года. С помощью приведенного ниже кода я могу достаточно легко получить среднее и стандартное значение, но мне нужно вызвать отдельную функцию начальной загрузки, чтобы получить 95% -й КИ для каждого года и каждой группы:
Это представление о том, как выглядят сгруппированные данные: (для 2013 года имеется 86 строк и 28 столбцов, а данные начинаются в 1970-х годах). Мне нужно использовать "bootsrap" для каждого столбца в сгруппированных для каждого года в сгруппированных.
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
`А вот мои функции для групповой загрузки и начальной загрузки:
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]
линия. Я подозреваю, что мне нужно быть более конкретным, чем использовать 'grouped' для поля данных в начальной загрузке, но я не уверен, как это сделать. Нужно ли применять это как лямбда-функцию? Или, может быть, с циклом? Любые предложения будут высоко ценится.
Посмотрев на эту страницу: 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])
Если бы это сработало, у меня было бы lo и hi для каждого из 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
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