У меня есть несколько временных рядов с наблюдениями в виде строк (индексированных меткой времени, 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