Python — подсчитывает количество записей, происходящих между двумя датами, путем сопоставления / сравнения переменных из нескольких фреймов данных

#python #pandas #datetime #for-loop #count

#python #pandas #дата и время #для цикла #подсчет

Вопрос:

У меня есть два фрейма данных: один содержит сообщения в социальных сетях (SM), другой содержит ответы с отметками времени для завершения опроса и время за 60 дней до завершения опроса (неточно для примера фрейма данных, не думаю, что это повлияет на методы, рассчитанные с -timedelta(days=60) использованием pd.datetime ).

social_media :

Публикация postedTime FIPS
‘aaa’ 2019-02-09 20:28:26 01010
‘bbb’ 2019-01-11 14:11:30 01010
‘ccc’ 2017-11-23 09:10:11 99999

survey :

Время соревнования 60daysprior FIPS
2019-01-08 11:28:26 2018-12-09 20:28:26 01010
2019-01-04 07:30:21 2018-11-11 14:11:30 01010
2017-07-14 07:30:21 2017-09-23 09:10:11 88888
2019-06-21 11:43:17 2019-04-23 09:10:11 77777

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

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

 import pandas as pd
import datetime
import itertools

full_count = []

for i, surveyrow in survey.iterrows():
    count = 0
    for j, SMrow in social_media.iterrows():
        if surveyrow['FIPS'] == SMrow['FIPS']:
            if surveyrow['completionTime']>=SMrow['postedTime']:
                if surveyrow['60daysprior']<=SMrow['postedTime']:
                    count =1
                else:
                    count =0
            else:
                count =0
        else:
            count =0
    full_count.append(str(count))

survey['count'] = full_count

 

Что я могу сделать для оптимизации этого кода? Я использую Python 3 и pandas . Спасибо!!

Обновление: этот код повышает скорость, но по-прежнему занимает много времени:

 survey_fips = survey['FIPS']
social_media_fips = social_media['FIPS']
survey_tm_finish = survey['completionTime']
social_media_postedTime = social_media['postedTime']
survey_tm_finish_minus60 = survey['60daysprior']

full_count = []


for i, j, k in zip(survey_fips, survey_tm_finish, survey_tm_finish_minus60):
    count = 0
    for a, b in zip(social_media_fips, social_media_postedTime):
        if i == a:
            if j>=b:
                if k<=b:
                    count =1
                else:
                    count
            else:
                count
        else:
            count
    full_count.append(str(count))
 

Комментарии:

1. Я думаю, вы можете использовать pd.merge_asof с by параметром, tolerance , и direction .

2. Спасибо @scott-boston. Возникли проблемы с реализацией этого. Буду ли я включать все переменные, проходящие через цикл, в by параметр? Я хочу подсчитать вхождения, так pd.merge_asof что это поможет? Не уверен из документации и примеров, которые я нашел.

3. Объедините два фрейма данных и используйте groupby для подсчета записей.