Статистика рождения детей по месяцам и неделям. Статистика смертности в россии Статистика дней рождения по месяцам

Каждая беременность индивидуальна, как и последующее появление малыша на свет. Хотя в процессе прослеживаются общие закономерности, которые отражает статистика родов по неделям (и другим показателям).

Нормы и сроки

Если обратить внимание на особенности статистического анализа деятельности родильных домов, можно понять, что большинство женщин производят малышей в положенный им срок – с 38-й до 40-й недели. Даты предполагаемых родов могут не совпадать с реальными на несколько суток, и связано это с менструальным циклом.

При подсчетах гинеколог берет усредненный вариант, но у одних месячные повторяются каждые 23 дня, у других через 30 и даже 40. Отклонение на неделю-две в ту или иную сторону от стандартного срока считается нормой.

Небольшой процент женщин, как показывает статистика начала родов по неделям, недонашивают детей. В первую очередь, это мамы с диагнозом «многоплодие», ведь 2-3-х малышей не реально доносить до стандартного срока. Еще меньшее количество рожает после 41-й недели.

Влияют на появление ребенка раньше или позже срока различные факторы: генетика, физическое состояние беременной, психологическая готовность к родам. Одной из причин считается возраст женщины.

Во сколько лет рожают в России? В начале века девушки стремились пораньше обзавестись семьей. Сейчас многие на первое место ставят карьеру, отодвигая сроки для зачатия на более поздний период. Поэтому первенца в стране 50% женщин рожают после 25 лет.

Во сколько лет рожают в Европе? В странах ЕС средний возраст для первых родов составляет 28-29 лет. Около 40% европеек становятся мамами в 35-39 лет, и небольшой процент после 45. Связано это с рациональным подходом к жизни – сначала нарабатывают материальную базу, затем заводят семью.

В каком месяце больше рождается детей по статистике? Как ни странно чаще всего рождаются дети, в середине осени – начале зимы. Зачатие происходит в морозные месяцы, когда появляется свободное время для семейного общения.

Женский организм за лето набрался сил, ультрафиолет и витамины укрепили иммунитет. Качество спермы у мужчины повышается в холодное время года. Эти факторы становятся благодатной почвой для оплодотворения.

В статистике рождений по месяцам второе место отводится маю-июню. На «бархатный сезон» приходится максимум свадеб и романтических путешествий, приводящих к зачатию новой жизни.
Если обратиться к статистике по времени суток, то большинство деток предпочитают появляться ближе к ночи либо под утро. Истинную причину этому ученые пока не обнаружили, поэтому высказывают только предположения. По одной версии виной всему белковый протеин, вырабатываемый плодом именно в ночное время. Другие считают, что расслабленность организма мамы дает команду активизировать родовую деятельность.

Срок родов у первородящих и повторнородящих

В народе бытует мнение, что вторые и последующие роды наступают раньше предполагаемого срока. Такое суждение правдиво частично – на вынашиваемость влияет не столько очередность беременности, сколько иные факторы.

Во сколько недель рожают при вторых родах? Малыш может появиться на свет в запланированную дату либо раньше назначенного срока. Небольшой процент повторнородящих перехаживает. Если женщина первенца родила после 41-й недели, и во втором случае происходит то же самое, можно говорить о генетической предрасположенности.

Статистика вторых родов по срокам незначительно отличается от динамики, прослеживаемой у первородок. А вот причины, влияющие на ранее появление младенца, у повторнородящих несколько иные.

Второго ребенка многие женщины заводят ближе к 30-годам, когда организм уже накопил болезни. Статистика 3 родов по срокам отмечает в 70% раннее появление младенца. Это происходит по причине спада активности репродуктивной системы.

Сам процесс родоразрешения у повторнородящих происходит быстрее – организм более подготовлен к ситуации. Отличительной особенностью последующих родов является отсутствие ложных схваток, в них просто нет необходимости. Ткани и мышцы матки, малого таза уже приобрели нужную эластичность, поэтому младенцу легче прокладывать себе путь наружу.

В случае с повторной беременностью двойней женщине приходится быть максимально осторожной. Первые роды наступают на 3-4 недели раньше срока, поэтому во вторых разрешение от бремени приходится на 7-8 месяц.

При нормальном ходе многоплодной беременности масса каждого малыша из двойни в среднем составляет 2,5 кг. Даже крепкая матка такой вес с трудом сдерживает, и раскрытие шейки происходит раньше времени.

В группу риска относят женщин с резус-фактором. Если первые роды у них происходят в срок, максимально приближенный к норме, то повторная беременность чаще всего оказывается недоношенной.

Статистика рождения мальчиков и девочек

Иногда можно услышать высказывание, что перед войной рождается больше мальчиков, но официальной статистикой это мнение не подтверждается. На пол ребенка влияют XY-факторы родителей, а не социально-политическое окружение.

Кого рождается больше, мальчиков или девочек? Биологические исследования с уверенностью доказывают, что при зачатии зигот мальчиков получается больше, чем девочек процентов на 50. Хотя до рождения доживают не все. Статистика рождения мальчиков такова – на каждые 100 девочек приходится 107 пацанят.

Не совсем верно и утверждение о том, что мальчиками перехаживают. Большинство из них рождается в срок, а вот девочек не всегда донашивают (особенно в повторных беременностях). Связано это с особенностями организма, заложенными природой, – женские клетки созревают быстрее и становятся выносливее.

Статистика рождаемости мальчиков в преждевременных родах показывает малый процент выживаемости младенцев. Девочки в этом плане оказываются более живучими, что особенно заметно при рождении двойняшек.

Если недоношенными на свет появляются девочки, у них больше шансов выжить. В разнополой двойне мальчики рождаются менее развитыми физически, чем сестры. Поэтому в преждевременных родах больше риск смертей.

Что касается появления на свет относительно времени суток или сезона, то половая принадлежность здесь роли не играет. «Иксы» и «игреки» не оказывают влияния на качество родовой деятельности во второй беременности, если она проходит без патологий.

Мальчики и девочки с одинаковой активностью появляются на свет. Что касается первородок, то по статистике дочек рожать легче. Они меньше весят, поэтому чаще идут естественным путем. Треть мальчишек родились с помощью кесарева сечения.

Некоторые ученые пришли к выводу, что беременность сыном снижает женский иммунитет из-за повышенного уровня тестостерона в крови. Это не только делает проблемным вынашивание ребенка, но и способно осложнить роды.

Осложнения ранних и поздних родов

Несмотря на то, что средний возраст рожениц составляет 25 лет, 13% приходится на ранние беременности и 37% на мам зрелых. В обоих случаях наблюдаются патологии и аномалии родовой деятельности.

Во сколько рожать первого ребенка? Медицина рекомендует зачинать детей, когда организм физиологически будет к этому готов. Данная фаза в жизни женщины наступает после 19 лет и длится до 35. Желательно вложиться в этот период, чтобы родить не только первого малыша, но и 2-3-его.

Беременность в раннем возрасте влияет негативно на развитие плода, если организм юной мамы еще до конца не сформировался. Чем меньше лет женщине, тем больше риск появления на свет недоношенного малыша. При этом родовая активность слабая, а этапы стремительные. В результате девушка получает сильные разрывы промежности и шейки. Возможны обильные кровотечения.

Если беременной меньше 18 лет, таз не до конца сформирован, поэтому клинически не соответствует размерам плодной головки. Ситуация влечет угрозу жизни, тогда единственно правильное решение – это кесарево сечение.

Не менее опасными считаются роды в зрелом возрасте. Ближе к 40 годам начинается регресс репродуктивности. Женщине сложнее вынашивать ребенка, особенно в первой беременности. Больше рисков позднего токсикоза, гестоза, анемии и аномального развития младенца.

Ткани теряют эластичность, мышцы становятся менее упругими, возникают проблемы с суставами и костями. Это приводит к осложнениям в родах, проявляющимся гипоксией плода, преждевременным разрывом пузыря, слабой деятельностью. В поздних беременностях статистика отмечает большой процент родов раньше срока, но бывают и перенашивания.

На зачатие после 40 осознанно идут чаще всего те, кто лечился от бесплодия. Женщины обращаются в ЭКО-центры, как к последней надежде на полноценную семью. Им обеспечивается постоянный медицинский контроль, цель которого – снизить до минимума возможные осложнения.

По статистике в мире каждую минуту рождается больше 250 детей, 3-е из которых появляются в России. Эти радостные события происходят днем и ночью в любое время года. Мальчиков и девочек производят на свет мамы разных возрастов и национальностей. Одних малышей донашивают до срока, других нет, третьи не спешат разорвать связующую с мамой пуповину. Все эти моменты фиксируются официальной статистикой и отображаются на демографических схемах, показывающих, как прогрессирует мир.

На основе данных Министерства здравоохранения РФ Федеральная служба государственной статистики (Росстат) собирает статистику о смертности в России. Статистика общедоступна, с её помощью все желающие могут узнать, каковы причины смертности в России, как меняются демографические показатели в России в целом и на её отдельных территориях по годам.

Подробнее познакомится с анализом статистики смертности в России вы можете в предлагаемой ниже статье.

Причины смертности в России

Основные причины смертности в России в 2016 г.

Всего в 2016 году умерло 1 891 015 россиян.

    Чаще всего к смерти приводили: болезни системы кровообращения – 904 055 смертельных случаев, в частности ишемическая болезнь сердца унесла 481 780 жизни.

    Злокачественные образования являются второй основной причиной смертности в России – от этой группы болезней скончалось 295 729 человек.

    Третья основная причина смертности – так называемые «внешние причины смерти». Эта категория включает несчастные случаи, убийства, самоубийства, нанесение травм, приведших к смерти и т.д. Всего по указанным причинам скончалось 167 543 человека.

    Частыми причинами смерти становились ДТП (15 854), случайные отравления алкоголем (14 021) и самоубийства (23 119).

    Отравление алкоголем также является существенной причиной смертности в России – от спиртного и болезней, вызванных чрезмерным употреблением алкоголя, скончалось 56 283 человек.

Всего в указанный период умерло 1 107 443 россиян.

Сравнительная статистика за 2016 и 2017 год

Сравнение статистики за 2016 и 2017 год дает возможность установить, как меняются причины смертности в России. Поскольку на сегодняшний день отсутствует полные статистические данные по 2017 году, сравним данные за первое полугодие 2016 и 2017 года.

В целом можно увидеть, что число умерших в период с января по июль в сравнении с прошлым годом сократилось на 23 668 смертей. Несмотря на то что число скончавшихся от болезней систем кровообращения снизилось на 17 821 человека, эта причина смертности остается ключевой и значимой – 513 432 смертей за указанный период. Существенно снизилось число людей, ставших жертвой внешних причин смерти – травмы и отравления стали причиной 80 516 смертей в первой половине 2016 г. против 90 214 в первом полугодии 2017-го. Важно учитывать, что эти числа являются предварительными, и общая годовая статистика может быть менее оптимистичной.

Смертность в России по годам

Хотя относительное улучшение ситуации в 2017 году выглядит оптимистично, следует также учитывать, что это следствие долгого процесса. В период между 1995 и 2005 годом ежегодная смертность колебалась между 2,2 и 2,36 млн человек. Начиная с 2006 года наблюдается снижение ежегодного числа умерших. Так, в 2005 году скончалось 2 303 935 человек, в то время как в 2006 цифра снизилась до 2 166 703, а уже 2011 году впервые за долгое время стала ниже 2 млн человек. В 2013 и 2014 гг. прирост населения впервые стал выше смертности, хотя число умерших поднялось с 1 871 809 до 1 912 347 человек. После скачка 2014-го года, статистика смертности в России продолжала снижаться, что демонстрируют числа за 2015 и 2016 гг, а также предварительные данные по 2017 г. К сожалению, снижение смертности в России обуславливается многими причинами, в том числе и высокой смертностью среди пожилого населения страны в предшествующие годы. Именно люди пенсионного возраста являются самой большой демографической группой среди умерших в России.

Смертность в России по месяцам

Анализ статистики по месячной смертности в России за промежуток в десять лет с 2006 по 2015 года дает возможность установить, в какие месяцы происходит наибольшее число смертей. Из всех месяцев наиболее высокая смертность в январе – в среднем 9,15% смертей. При этом важно учитывать неточности в статистике – немалое число смертей, случившихся в декабре, «переносятся» с декабря на январь. Довольно много граждан также умирают в марте и мае – 8,81% и 8,53% от средней годовой смертности. Наиболее же «безопасными» являются сентябрь и ноябрь – 7,85% и 7,89% от общего числа смертей за год приходится на эти месяцы.

Несколько дней назад в блоге The Daily Viz была опубликована запись , которая привлекла внимание широкой общественности как пример простой и эффективной визуализации данных.

Визуализация представляла собой карту популярности дней рождения, реализованную как теплокарта (heatmap) в виде календаря. По вертикали располагались числа, по горизонтали - месяцы, и, глядя в эту незамысловатую таблицу, мы могли по насыщенности оттенка судить о том, насколько популярен тот или иной день в году с точки зрения деторождения.

Через какое-то время автор визуализации опубликовал в том же блоге второй пост , извинившись за то, что ввел сообщество в заблуждение, не прокомментировав должным образом исходные данные , использованные в работе над изображением. Проблема была в том, что исходный сет данных не содержал информации о реальном числе родившихся в тот или иной день людей. Информация была дана в другом виде - на каком месте (rank) находится тот или иной день в «рейтинге» популярности дней рождения.

То есть, разница между первой и второй позицией в рейтинге могла быть колоссальной (скажем, в два раза), но отличались бы они все равно только на один тон. Иными словами, визуализация не отражала реальных данных из-за того, что сет содержал лишь производные данные.

Немного подумав над этой проблемой, я решил описать собственный пример создания такой визуализации от начала до конца - т. е. от сбора данных до, собственно, отрисовки изображения. Этот пример хорош тем, что он, с одной стороны, относительно прост, а с другой - является целостным завершенным проектом с определенным интересным результатом.

Для всех операций я использовал среду Processing, которая традиционно используется для подобных задач (на проблеме выбора инструмента подробно останавливаться не стоит).

Итак, процесс работы над проектом имеет устойчивую структуру и состоит из трех этапов:
сбор данных > cортировка данных > визуализация данных

Будем следовать этой структуре.

1. Сбор данных

Данные будем извлекать из профилей пользователей социальной сети vk.com. К счастью для нас, некоторые методы ее API являются открытыми и не требуют авторизации приложения, что значительно упрощают задачу.

Опытным путем я установил, что данных 100 000 профилей будет достаточно для того, чтобы нивелировать случайные неоднородности в распределении дней рождения в календаре и выявить основные тенденции. Тем не менее, для экономии времени и демонстрации соберем 10 000 записей. Позже мы сможем подставить в программу любое нужное нам число профилей.

Писать программу мы будем внутри основной функции setup() . Функция draw() нам не понадобится, поскольку программа генерирует статичное изображение и не содержит анимации. Подробнее со структурой программы на Processing можно ознакомиться на сайте проекта. Там же есть описание всех встроенных функций и прекрасный справочник по синтаксису.

Кроме того, мы не будем писать программу, которая выполняет задачу от и до: собирает данные, обрабатывает их и создает визуализацию. Разделим «слона» на несколько модулей, чтобы было проще работать и тратить меньше времени на отладку и устранение ошибок. Т. е. сначала напишем программу, которая собирает данные, соберем с ее помощью данные. Затем отдельно напишем программу, которая на основе сохраненных собранных данных генерирует требуемое изображение.

Итак, пишем болванку-заготовку для программы.

Void setup() { //наша основная функция exit(); //выходим из программы }

Теперь разберемся, как работает VK API. Мы обращаемся к серверу по специальному URL, содержащему параметры нашего запроса:

Http://api.vk.com/method/users.get.xml/uids={здесь список id интересующих нас пользователей через запятую}&fields={здесь список названий интересующих нас полей профиля пользователя}

Если мы напишем имя метода без.xml, то получим ответ от сервера в виде строки в формате JSON. Это один из вариантов, но в данном примере мы будем использовать XML. Предположим, мы хотим получить информацию из аккаунта Павла Дурова, основателя vkontakte. Наш адрес:

Http://api.vk.com/method/users.get.xml?uids=1&fields=bdate

Id его профиля - 1, интересующее нас поле - день рождения - называется bdate .

Попробуем получить информацию об этом профиле. Используем встроенную функцию loadStrings() , которая в качестве параметра принимает строку с адресом интересующего нас файла, а возвращает содержимое файла в виде массива строк.

Void setup() { String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=1&fields=bdate"); //загружаем информацию println(user); //выводим содержимое массива (ответ сервера) в консоль exit(); //выходим из программы }

После запуска программы в консоли появится наш ответ от сервера:

"" "" " " " 1" " Павел" " Дуров" " 10.10.1984" " " ""

Числа в квадратных скобках означают номер записи (index) в массиве и не имеет отношения к содержимому массива. Также каждая строка заключена в кавычки. Собственно, то, что находится между кавычками, и есть наше содержимое. Нас интересует поле

(строка ). Оно содержит интересующую нас информацию - дату рождения пользователя №1 в понятном формате: 10 число 10 месяца (октября) 1984 года.

Мы договорились собрать 10 000 дат рождения. Что мы делаем? Перебираем id пользователей от 1 до нужного нам числа. Проблема заключается в том, что не все id имеют действующие профили и не все пользователи открывают свою дату рождения. Таким образом, нам нужно два счетчика: первый счетчик будет отсчитывать id пользователей по порядку, а второй будет считать, сколько дат мы действительно собрали, чтобы вовремя остановиться. По опыту, чтобы набрать 10 000 дат, нужно перебрать около 15 000 аккаунтов.

Пишем цикл:

Void setup() { int count = 0; //счетчик успешных обращений к серверу for (int i = 1; count <= 10000; i++) { //перебираем id, не останавливаемся, пока счетчик успешных обращений меньше или равен 10000 String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); //загружаем информацию, подставляя счетчик на место id for (int j = 0; j < user.length; j++) { //перебираем все строки ответа if (user[j].indexOf("") != -1) { //если строка содержит интересующее нас поле println(i + "\t" + count + "\t" + user[j]); //выводим данные в консоль count++; //увеличиваем счетчик успеха на 1 } } } exit(); //выходим из программы }

Заметьте, что значение счетчика i , когда мы подставляем его в строку, «обернуто» функцией str() . Она нужна для перевода типа данных из числа в строку. Строго говоря, программа поймет что мы от нее хотим и без этой операции, но лучше сразу взять за привычку контролировать такие вещи, как перевод данных из одного типа в другой (в некоторых ситуациях автоматический перевод не работает).

При переборе строк ответа мы используем метод indexOf() , который возвращает местоположение указанной в параметре строки в строке, к которой применяется метод. Если в нашей строке строки-параметра нет, метод возвращает значение -1, чем мы и пользуемся для проверки того, является ли текущая строка нужной нам.

Когда мы выводим интересующие нас данные в консоль, добавим дополнительную информацию: состояние счетчиков, чтобы следить за прогрессом. Значения переменных в скобках функции вывода println() разделены строкой "\t" , которая означает символ табуляции.

Если сейчас запустить программу, мы увидим, что значения счетчиков быстро расходятся. В моем случае после перебора 55 id была собрана только 31 дата.

Итак, кажется, всё работает нормально, осталось только заставить программу записывать данные в файл по мере поступления. Для этого создадим объект класса PrintWriter . Он объявляется как обычная переменная, и ему как правило сразу присваивается значение функции createWriter(путь к файлу) :

PrintWriter p = createWriter("data/bdates.txt");

В данном случае мы именуем объект «p», привязывая к нему файл по адресу «папка-программы/data/bdates.txt», что позволит нам записывать в этот файл то, что нам нужно. Как мы это делаем? К нашему объекту можно применить метод println() , который работает так же, как одноименная функция, но выводит данные не в консоль, а в указанный файл. Выглядит это так:

P.println(данные);

После того, как мы поработали с нашим файлом, нужно корректно завершить работу с ним, иначе информация в него не запишется. Делается это с помощью такой записи:

P.flush(); p.close();

Эти две функции всегда используются для корректного завершения работы с файлом вместе. Наша программа:

<= 10000; i++) { //перебираем id, не останавливаемся, пока счетчик успешных обращений меньше или равен 10000 String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); //загружаем информацию, подставляя счётчик на место id for (int j = 0; j < user.length; j++) { //перебираем все строки ответа if (user[j].indexOf("") != -1) { //если строка содержит интересующее нас поле p.println(user[j]); //записываем результат в файл println(count); //выводим счетчик в консоль для наблюдения за прогрессом count++; //увеличиваем счетчик успеха на 1 } } } p.flush(); p.close(); //завершаем работу с файлом exit(); //выходим из программы }

При сборе данных мы отказались от вывода значения строки и счетчика id в консоль: вывод слишком большого количества данных в консоль иногда может тормозить работу программы, поэтому лучше ограничиться только необходимым - счетчиком собранных дат.

Казалось бы, что еще нужно? Можно запускать программу! И да, и нет. При опросе удаленного сервера всегда нужно иметь в виду, что иногда сервер не отвечает. Представим, что мы отправили запрос к серверу, ждем ответа и не получаем его. Через какое-то время программа решит, что сервер «лежит» и просто продолжит выполняться дальше. Что будет? Ведь мы не получили данные о пользователе, наш массив пустой. Если программа к нему обратится, программа выдаст в консоль сообщение об ошибке и остановится. Этого может и не произойти, но может и произойти, и тогда придется снова запускать программу, ждать и молиться о том, чтобы сервер ответил на все 15 000 наших запросов.

Чтобы не полагаться на слепую судьбу, была изобретена обрабока ошибок. Ошибки обрабатываются с помощью вот такой записи:

Try { //здесь код, который может вызвать сбой } catch (здесь тип ошибки) { //здесь код, который выполняется в случае, если ошибка произошла }

Программа с обработкой ошибок:

Void setup() { PrintWriter p = createWriter("data/bdates.txt"); //объект для вывода данных в файл int count = 0; //счетчик успешных обращений к серверу for (int i = 1; count <= 10000; i++) { //перебираем id, не останавливаемся, пока счетчик успешных обращений меньше или равен 10000 String user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); //загружаем информацию, подставляя счётчик на место id try { for (int j = 0; j < user.length; j++) { //перебираем все строки ответа if (user[j].indexOf("") != -1) { //если строка содержит интересующее нас поле p.println(user[j]); //записываем результат в файл println(count); //выводим счетчик в консоль для наблюдения за прогрессом count++; //увеличиваем счетчик успеха на 1 } } } catch (Exception e) {} } p.flush(); p.close(); //завершаем работу с файлом exit(); //выходим из программы }

Теперь, если возникает ошибка при обращении к массиву (если массив пустой), выполнится код… никакого кода не выполнится, программа выведет сообщение об ошибке, но не остановится. Мы просто игнорируем ошибку и идем дальше - всего-то придется запросить информацию еще одного пользователя. Тип ошибки указан Exception , это значит, что мы «ловим» любые ошибки, которые возникнут. Запись e после типа ошибки требуется, потому что программе нужна какая-то переменная, в которую можно записать информацию об ошибке. Мы можем обращаться к этой переменной при обработке ошибок, однако в данном случае это не нужно.

2. Сортировка данных

Через какое-то время (обычно не больше получаса) после запуска программы она завершится и мы увидим в консоли заветное число 10 000. Это значит, что данные собраны и можно начинать сортировку. Откроем файл в текстовом редакторе и посмотрим на результат наших трудов:

Что не так? Ага, мы совсем забыли, что записывали в файл данные вместе с XML-тегами. Не беда! В любом текстовом редакторе есть функция автозамена, с помощью которой можно почистить наш файл от лишней информации. Строго говоря, мы могли бы программно «отловить» лишнее уже на этапе сбора данных, но в принципе, для простоты и экономии времени не зазорно воспользоваться любым доступным инструментом.

Почистив файл, сохраняем его и закрываем. Теперь программе будет просто его читать.

3. Визуализация данных

А теперь займемся отрисовкой. Сначала нам нужно открыть файл и посчитать, сколько же пользователей родилось в каждый отдельный день. Для открытия файла используем старую знакомую функцию loadStrings() . Для того, чтобы хранить количество пользователей, родившихся в определенный день, используем двухмерный массив натуральный чисел:

Int table = new int

Мы указали размер массива 12 на 31. В году у нас 12 месяцев и максимум 31 день. По идее, 31 февраля не должно родиться ни одного человека, поэтому нас не должно волновать, что массив для некоторых месяцев слишком длинный.

Как будет работать наша программа? Мы должны взять дату, определить, какой в ней содержится день и месяц, и увеличить соответствующую ячейку массива на единицу.

Для того, чтобы разбить строку на числа дня, месяца и года, мы будем использовать метод split() . Он возвращает массив строк, а принимает в качестве аргумента строку-разделитель: инструкция

String s = "00010010".split("1");
присвоит массиву s значение
"000" "00" "0"

Что это означает для нашей практики? Мы берем строку массива и делим ее с помощью символа точки в качестве разделителя. Есть одна техническая проблема: символ точки зарезервирован в качестве обозначения любого символа. Поэтому вместо "." в качестве аргумента мы передаем "\\." - такая запись обозначает нужный нам символ точки. Получается так:

< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты } exit(); //выходим из программы }

Теперь в ячейке date содержится строка с номером дня в месяце, а в date - номер месяца. Мы должны увеличить соответствующую ячейку массива table на единицу:

Table++;

Указывая адрес ячейки соответствующий дате, мы переводим строку в число с помощью функции int() , а также отнимаем единицу. Зачем отнимать единицу? Затем, что отсчет ячеек массива начинается с нуля. Мы указали длину 12, это значит, что ячейки массива имеют нумерацию от 0 до 11. В отличие от месяцев, которые нумеруются от 1 до 12. Об этом несоответствии необходимо помнить.

Правильно? Правильно, да не совсем. Если сейчас запустить программу, она выдаст ошибку. Дело в том, что наш сет данных не идеален. По какой-то неведомой причине у некоторых пользователей в поле даты рождения стоят какие-то непотребные числа вроде 666.666 или 32.13.888888888. Иногда можно даже встретить пользователя, который родился, к примеру, минус пятого декабря. Чтобы их отсортировать, нужно отбросить значения месяцев больше 12 и значения дней больше 31, а также все значения меньше или равные нулю:

If ((int(date) <= 12) && (int(date) > 0) && (int(date) <= 31) && (int(date) > 0)) { //если с числом все в порядке table++; //увеличиваем ячейку таблицы на 1 }

Программа целиком:

Void setup() { String file = loadStrings("data/bdates.txt"); //загружаем файл с данными int table = new int; for (int i = 0; i < file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) > 0) && (int(date) <= 31) && (int(date) > 0)) { //если с числом все в порядке table++; //увеличиваем ячейку таблицы на 1 } } exit(); //выходим из программы }

Теперь, когда данные наконец собраны и хранятся в памяти программы, можно наконец-то приступить к творчеству - рисованию. Сначала определимся с цветом, которым мы будем рисовать: я взял фирменный синий цвет VK: RGB 54, 99, 142. Объявим переменную-цвет, чтобы не писать каждый раз три заветных числа:

Color c = color(54, 99, 142);

Также нам нужно (по традиции, в самом начале программы) решить, какой ширины и высоты будет наше изображение. Для этого напишем функцию:

Size(ширина, высота);

Какая у нас будет ширина и высота? Предположим, каждая ячейка теплокарты будет шириной 40 пикселей плюс один пиксель для отступа между ячейками. Месяцы откладываем по ширине. Не забываем про отступ от край (10 пикселей). Получается 20+41*12. Если не хочется считать в уме или открывать приложение-калькулятор, можно просто написать это выражение как аргумент функции println(20+41*12); и получить ответ - 512. Это ширина изображения. С учетом высоты ячейки в 20 пикселей и такого же отступа от края, получаем:

Size(512, 671);

Теперь временно уберем команду exit(); в конце программы, чтобы мы не выходили из программы после завершения, и запустим выполнение кода:

< file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) > 0) && (int(date) <= 31) && (int(date) > 0)) { //если с числом все в порядке table++; //увеличиваем ячейку таблицы на 1 } } color c = color(54, 99, 142); //цвет }

После указания размера кадра я добавил команду установить белый фон: если мы указываем цвет одним числом, то он распознается как оттенки серого от 0 (черный) до 255 (белый). При запуске программы должно открыться окно с белым фоном нужного нам размера.

Начнем, наконец, рисовать. Как мы рисуем? Пробегаемся по массиву table - по каждой строке (месяц) и в каждой строке (день этого месяца) по ячейкам. Рисуем в нужном месте и нужным цветом прямоугольник 40 на 20. Как вычисляется позиция X? 10(отступ) + 41(ширина+зазор между) * i(счетчик месяцев). Позиция Y? 10(отступ) + 21(высота+зазор между) * j(счетчик дней). Прямоугольник рисуется функцией rect(x, y, ширина, высота); -

Rect(10+41*i, 10+21*j, 40, 20);

Программа:

Void setup() { size(512, 671); //устанавливаем размер background(255); //цвет фона - белый String file = loadStrings("data/bdates.txt"); //загружаем файл с данными int table = new int; for (int i = 0; i < file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) > 0) && (int(date) <= 31) && (int(date) > 0)) { //если с числом все в порядке table++; //увеличиваем ячейку таблицы на 1 } } color c = color(54, 99, 142); //цвет for (int i = 0; i < table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням rect(10+41*i, 10+21*j, 40, 20); //рисуем прямоугольник в нужной позиции } } }

Если запустить этот код, мы получим поле, странным образом расчерченное прямоугольниками с обводкой. Сначала уберем обводку, добавив перед рисованием команду noStroke(); . Теперь установим наш цвет в качестве заливки: fill(c);

Прекрасно. Теперь площадь замощена красивыми синими плиточками с белыми промежутками. Дальше нам нужно каким-то образом закодировать значения таблицы в цвет заливки. Сделаем это с помощью прозрачности. Прозрачность цвета принимает значения от 0 до 255. Запись fill(c, 10); даст едва заметный синеватый оттенок, а запись fill(c, 240); даст почти что полностью насыщенный синий цвет. Итак, диапазон прозрачностей - 0..255. Диапазон значений в нашем массиве гораздо больше (или меньше). Предположим, мы знаем максимальное значение в массиве. Минимальным, понятное дело, будет ноль. Нам нужно как-то вписать значение из массива в диапазон 0..255, как бы уменьшив (увеличив) масштаб. Для этого существует функция map(значение, начало исходного диапазона, конец исходного диапазона, начало нового диапазона, конец нового диапазона) :

Map(table[i][j], 0, 1000, 0, 255);

Здесь мы сделали предположение, что максимальное значение массива - 1000. Тогда при значении table[i][j] в 1000 функция вернет 255, а при значении 0 - вернет ноль.

Как же рассчитать минимальное и максимальное значение двухмерного массива? Для одномерного массива существуют функции соответственно min() и max() . Используем их. Пробежимся циклом по «месяцам» и сравним минимальное и максимальное значение каждого «месяца» (который воспринимается средой как одномерный массив) с переменными, хранящими текущее минимальное или максимальное значение в массиве. И не забудем еще одну важную вещь: иногда в сете данных встречались некорректные даты, т.е. кто-то мог указать дату рождения 31 ноября или 30 февраля. Чтобы этот факт нам не мешал, установим значение всех несуществующих дат на ноль.

Table = 0; //30 февраля table = 0; //31 февраля table = 0; //31 апреля table = 0; //31 июня table = 0; //31 сентября table = 0; //31 ноября int mi = table; //минимальное значение int ma = table; //максимальное значение for (int i = 0; i < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //если минимальное значение этой строки меньше текущего минимума и больше нуля mi = min(table[i]); //сделать это значение минимумом } if (max(table[i]) > ma) { //если максимальное значение этой строки больше текущего максимума ma = max(table[i]); //сделать это значение максимумом } } println(mi + " " + ma); //выводим значения

У меня значения получились 14 и 47. В принципе, это не важно, потому что мы можем использовать значения переменных. Теперь нам надо при каждом обращении к ячейке таблицы, т.е. перед рисованием каждого прямоугольника, установить свою заливку:

Void setup() { size(512, 671); //устанавливаем размер background(255); //цвет фона - белый String file = loadStrings("data/bdates.txt"); //загружаем файл с данными int table = new int; for (int i = 0; i < file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) > 0) && (int(date) <= 31) && (int(date) > < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //если минимальное значение этой строки меньше текущего минимума и больше нуля mi = min(table[i]); //сделать это значение минимумом } if (max(table[i]) > < table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням fill(c, map(table[i][j], 0, ma, 0, 255)); //считаем заливку rect(10+41*i, 10+21*j, 40, 20); //рисуем прямоугольник в нужной позиции } } }

Что мы видим после запуска программы? Плиточки стали разного цвета, в зависимости от количества родившихся в тот или иной день. Также мы видим, что 29 февраля имеет довольно отчетливый цвет. Очевидно, что количество родившихся в этот день минимально, а это значит, что мы теряем большую часть диапазона цветов, доступного для отображения (значения начинаются с 14, а у нас минимум стоит на 0 - это значит, мы не используем значения прозрачности навскидку примерно от 0 до 85. Непорядок. Поставим минимальным значением в функции map() не ноль, а 12, чтобы плиточка 29 февраля была едва заметна. Из-за того, что наш минимум теперь составляет 12, а не ноль, прозрачность тех плиточек, которые имеют значение 0, будет отрицательной. А поскольку при отрицательных значениях прозрачность откатывается циклически (-5 - это все равно что 250!), получится, что несуществующие дни будут не белыми, а темными. Добавим условие, при котором «нулевые» дни вообще не рисуются:

Void setup() { size(512, 671); //устанавливаем размер background(255); //цвет фона - белый String file = loadStrings("data/bdates.txt"); //загружаем файл с данными int table = new int; for (int i = 0; i < file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) > 0) && (int(date) <= 31) && (int(date) > 0)) { //если с числом все в порядке table++; //увеличиваем ячейку таблицы на 1 } } table = 0; //30 февраля table = 0; //31 февраля table = 0; //31 апреля table = 0; //31 июня table = 0; //31 сентября table = 0; //31 ноября int mi = table; //минимальное значение int ma = table; //максимальное значение for (int i = 0; i < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //если минимальное значение этой строки меньше текущего минимума и больше нуля mi = min(table[i]); //сделать это значение минимумом } if (max(table[i]) > ma) { //если максимальное значение этой строки больше текущего максимума ma = max(table[i]); //сделать это значение максимумом } } color c = color(54, 99, 142); noStroke(); for (int i = 0; i < table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням if (table[i][j] > 0) { fill(c, map(table[i][j], 12, ma, 0, 255)); //считаем заливку rect(10+41*i, 10+21*j, 40, 20); //рисуем прямоугольник в нужной позиции } } } }

Но что мы видим? Среди окружающих дней как-то особенно выделяется 1 января. Та же тенденция сохраняется на гораздо больших числах пользователей. Когда я собирал данные по 300 000 аккаунтов, 1 января точно так же сияло глубоким синим, а остальные цвета были бледными. Очевидно, такое явление связано с действиями пользователей, которые, не желая публиковать свой реальный день рождения, выбирают первое число в списке. Отделить действительно родившихся в Новый год от жалких симулянтов не представляется возможным. Чтобы выровнять сет, просто удалим оттуда данные, присоив ячейке table значение ноль. Чтобы сохранить картинку, используем команду saveFrame(«frame.jpg»); в самом конце программы. У нас появится соответствующий файл в папке с программой.

Код программы полностью:

Void setup() { size(512, 671); //устанавливаем размер background(255); //цвет фона - белый String file = loadStrings("data/bdates.txt"); //загружаем файл с данными int table = new int; for (int i = 0; i < file.length; i++) { //перебираем все строки файла String date = file[i].split("\\."); //переводим строку в массив, содержащий числа даты if ((int(date) <= 12) && (int(date) > 0) && (int(date) <= 31) && (int(date) > 0)) { //если с числом все в порядке table++; //увеличиваем ячейку таблицы на 1 } } table = 0; //1 января table = 0; //30 февраля table = 0; //31 февраля table = 0; //31 апреля table = 0; //31 июня table = 0; //31 сентября table = 0; //31 ноября int mi = table; //минимальное значение int ma = table; //максимальное значение for (int i = 0; i < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //если минимальное значение этой строки меньше текущего минимума и больше нуля mi = min(table[i]); //сделать это значение минимумом } if (max(table[i]) > ma) { //если максимальное значение этой строки больше текущего максимума ma = max(table[i]); //сделать это значение максимумом } } color c = color(54, 99, 142); noStroke(); for (int i = 0; i < table.length; i++) { //пробегаемся по месяцам for (int j = 0; j < table[i].length; j++) { //пробегаемся по дням if (table[i][j] > 0) { fill(c, map(table[i][j], 12, ma, 0, 255)); //считаем заливку rect(10+41*i, 10+21*j, 40, 20); //рисуем прямоугольник в нужной позиции } } } saveFrame("frame.jpg"); //сохраняемся }

Готово! Из получившейся картинки пока что не особенно понятны, как сейчас говорят, тренды, потому что мы собрали слишком мало данных. Вот картинка для 300 000 аккаунтов (нет, я не ждал для сбора данных 100 лет, а использовал асинхронные запросы к серверу - может быть, я когда-нибудь напишу о реализации их в Processing), на которой ясно видна тенденция (хотя и не очень яркая):

А анализ полученной визуализации ложится на ваши плечи! ;]

Вот, держи подкрашенный вариант: ссылка (https://transfiles.ru/m757t)
В эксельке это делается через условное форматирование/цветовые шкалы (в данном случае каждая строка подкрашена независимо от других)
+ добавил снизу среднее за весь период и средние по десятилетиям.

На протяжении 50-60 годов рекордная рождаемость отмечалась в январе, а самая низкая - в декабре, что удивительно, учитывая что месяца соседние. могу предположить 2 причины:
а - при рождении в декабре время зачатия приходилось на великий пост, а при рождении в январе - на промежуток времени между пасхой и интенсивными майскими полевыми работами.
б - детей, рождённых в декабре люди намеренно записывали (регистрировали) в январь. Про такую тенденцию мне бабушка рассказывала (кстати тётю мою она именно так зарегистрировала на январь, хотя по факту та рождена в декабре). Но в 70-х эта тенденция уменьшилась (или учёт стал вестись строже благодаря развитию родовспоможения).

В целом на протяжении всей второй половины 20-го века преобладала по деторождения весна. А если точнее, то в середине 20-го века преобладали зимне-весенние рождения (зачатие соответственно весной и в начале лета), а далее шло неуверенное смещения деторождений на весенне-летний период (то есть зачатия смещались на конец лета - начало осени - сезон отпусков) - что явно говорит об увеличении доли горожан, развитие городской культуры и деградации сельского общества. Причём в условиях кризисных 90-х произошёл откат этой тенденции на 20 лет назад - что может отражать деградацию экономики и широкого развития такого культурного явления как дачи/огороды/подсобное хозяйство (коими обзавелись многие горожане в 90-х). Отпуска использовались теперь не для отдыха (и зачатия), а для производства продовольствия для собственного пропитания.

С наступлением 21 века пик деторождений резко сместился на более поздний период, причём смещение произошло очень резкое и сильное (почти на полгода). С середины 00-х преобладающими по деторождению становятся летне-осенние. То есть зачатия сместились на осенне-зимние месяца (с октября по январь). Если это не косяк статистики, то получается любопытная картина. Наиболее плодотворными по зачатию стали тёмные-холодные месяцы, в которые люди стараются сидеть дома и как мы видим в буквальном смысле не вылазить из кровати.

Почему я назвал картину Любопытной. Дело в том, что по мере развития освещения (уличного и домашнего) и смещения периода бодрствования на всё более поздний срок (люди ложатся спать и просыпаются всё позднее) - зачатие детей постепенно смещается на всё более тёмное время года. Иными словами, когда электричества не было (или его старались беречь), детей зачинали в мае-июле, а когда в квартирах (и на улицах) освещение включено сутками напролёт (Москоу невер слип) - детей зачинают в октябре-декабре. Грубо говоря - делать детей интереснее при свете (а в темноте можно и промахнуться).