Отобрать статистически значимое количество значений в группе в датафрейме
Имеется фрейм данных:
data = {'id_поставки': ['101','102','103','250','255','260','290','0112', '7011', '0151','06611', '600', '56','96', '59', '235', '785'],
'месяц_поставки': ['январь','март','январь','март', 'сентябрь','март','март', 'март', 'ноябрь', 'январь','январь', 'март', 'январь','июль', 'март', 'март', 'апрель']
}
dates = pd.DataFrame(data, columns = ['id_поставки', 'месяц_поставки'])
В котором есть id поставки и месяц поставки.
Нужно получить датафрейм, в котором для каждого месяца будет статистически значимое количество число строк из dates.
Ожидаемый результат:
Для вычисления статистически значимого числа поставок для каждого месяца используется функция sample_size
def sample_size(population_size, confidence_level=90, confidence_interval=50):
confidence_level_constants = {
50: 0.67,
68: 0.99,
90: 1.64,
95: 1.96,
99: 2.57
}
p = 0.5
e = confidence_interval / 100.0
N = population_size
n_0 = 0.0
n = 0.0
Z = confidence_level_constants[confidence_level]
n_0 = ((Z**2) * p * (1-p)) / (e**2)
n = n_0 / (1 + ((n_0 - 1) / float(N)) )
return int(math.ceil(n))
Вычислить необходимый размер выборки для каждого месяца можно, применив sample_size к колонке id_поставки при группировке: data.groupby('месяц_поставки',as_index=False).agg({'id_поставки':'count'})
Как получить таблицу из ожидаемого результата?
Ответы (1 шт):
У вас уже почти всё готово.
Сначала нужно сделать серию с необходимым числом поставок для каждого месяца:
month_size = dates.groupby('месяц_поставки')\
.count()['id_поставки']\
.apply(sample_size)
Результат
месяц_поставки
апрель 1
июль 1
март 3
ноябрь 1
сентябрь 1
январь 3
Дальше просто. Нужно выбрать из dates нужное число строк из каждого месяца и собрать их в один фрейм.
Выборка строк. Для примера возьмём январь:
m = 'январь'
dates[dates['месяц_поставки'] == m][:month_size[m]]
Склеивание в один фрейм: pd.concat
Итого:
pd.concat([
dates[dates['месяц_поставки'] == m][:month_size[m]]
for m in month_size.index
])
Если вам нужно, чтобы нумерация строк была с нуля, то добавьте вызов метода reset_index:
pd.concat([
dates[dates['месяц_поставки'] == m][:month_size[m]]
for m in month_size.index
]).reset_index(drop=True)



