Pandas: объединить два фрейма данных и применить фильтр - PullRequest
1 голос
/ 13 апреля 2020

У меня есть 2 фрейма данных.

Фрейм данных 1

Userid | SessionID | Endtime
John   | '' | 0910
Paul   | '' | 0920
.....

Фрейм данных 2

UserID| SessionID | starttime|end time
John | 0 | 0905 | 0915
Jack | 1 | 0900 | 0915
....

Фрейм данных 1 имеет 333975 строк. Dataframe 2 имеет 2460 строк.

Я хочу пометить фрейм данных 2 со ссылкой на фрейм данных 1. Соответствие происходит, если пользователь в фрейме даты 1 = фрейм данных 2 пользователя, и если «конечное время» находится между «начальным временем» и «конечным временем», скопируйте SessionID от фрейма данных 1 до фрейма данных 2.

Мой код выглядит следующим образом:

For i in range(len(df1)) :
    For j in range(len(df2)) :
        if(df1['Userid'][1] == df2['UserID']) :
            if((df1['Endtime'] [i] > df2['starttime'][j]) & (df1['Endtime'] [i] < df2['end time'][j])) 
                df1['SessionID' ][i] = df2['SessionID'][j]

Ранее, когда я обработал 65 КБ d1, выполнение заняло 30 минут. Теперь с 333k это занимает часы.

Есть ли более эффективный способ сделать такую ​​маркировку?

Обновление: я также пытался использовать np.where, чтобы сделать это, но это также занимает много времени. Он пробежал 2 часа и продолжает считать.

Вот мой код:

df1['SessionID' ][i] = np.where( (df1['Userid'][1] == df2['UserID']) &  (df1['Endtime'] [i] > df2['starttime'][j]) & (df1['Endtime'] [i] < df2['end time'][j]), df2['SessionID'][j], df1['SessionID' ][i]) 

Ответы [ 2 ]

4 голосов
/ 13 апреля 2020

Вы можете объединить два фрейма данных и применить фильтр поверх него.

raw_data = {
    'user_id': ['John', 'Paul'],
    'session_id': [1, 2],
    'end_time' : [910, 920]
}
pd_a = pd.DataFrame(
    raw_data, columns=['user_id', 'session_id', 'end_time']
)

raw_data = {
    'user_id': ['John', 'Paul'],
    'session_id': [1, 2],
    'start_time': [900, 900],
    'end_time' : [915, 925]
}
pd_b = pd.DataFrame(
    raw_data, columns=['user_id', 'session_id', 'start_time', 'end_time']
)

final_pd = pd.merge(pd_a, pd_b, on='user_id')

Вывод

  user_id  session_id_x  end_time_x  session_id_y  start_time  end_time_y
0    John             1         910             1         900         915
1    Paul             2         920             2         900         925

затем, наконец, примените любой фильтр, к которому хотите.

final_pd[final_pd['end_time_x']<=final_pd['end_time_y']]
0 голосов
/ 13 апреля 2020

Вы можете попробовать управлять объектами второго оператора if как Pandas Series или списки, а затем, если условие удовлетворено, вы можете выполнить маркировку для набора данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...