У меня есть 2 таблицы в моей базе данных (visits
, events
).
посещения имеет первичный ключ visit_id
,
В events_and_pages есть столбец visit_id
, который является своего рода внешним ключом посещений. (строка events
может относиться к посещениям от 0 до 1)
Что я хочу сделать: отфильтровать из таблицы events
все visit_id
, которые не принадлежат таблице visits
. Простая задача.
У меня есть данные для каждой из этих таблиц, хранящиеся в pandas.DataFrame
, соответственно df_visits
и df_events
.
Делаю следующую операцию:
len(set(df_visits.visit_id) - set(df_events.visit_id))
Я получаю результат 1670, что соответствует моим ожиданиям.
Но, когда я делаю
filter_real_v = df_events.visit_id.isin(set(visits.visit_id))
filter_real_v.value_counts() # I get only True values
filter_real_v = df_events.visit_id.isin(visits.visit_id)
filter_real_v.value_counts() # I get only True values
Еще более странно, когда я использую
pd.DataFrame(df_events.visit_id).isin(real_visits)).visit_id.value_counts() #I get all False values except 8 that are True
pd.DataFrame(df_events.visit_id).isin(set(real_visits)).visit_id.value_counts() #I get all True values
Что здесь происходит? И как я могу определить фильтр, для которого visit_id
существует в events
, но не в visits
?
Пожалуйста, найдите по этой ссылке, CSV-файлы df_events
и df_visits
, чтобы воспроизвести эту ошибку (через запятую index,visit_id
)
Обновлено: добавить фрагмент для минимального воспроизводимого кода:
file_path_events
и file_path_visits
по вашему выбору.import pandas as pd
events = pd.read_csv("df_events.csv")
events.set_index('index',inplace=True)
visits = pd.read_csv("df_visits.csv")
visits.set_index('index',inplace=True)
correct_delta = len(set(visits.visit_id) - set(events.visit_id))
print(correct_delta) #1670
filter_real_v = events.visit_id.isin(set(visits.visit_id))
bad_delta = filter_real_v.value_counts()
print(bad_delta[True]) #702680
С наилучшими пожеланиями
@anky_91 Я пытался, но мой браузер вылетает
Не уверен, что не так с вашим фрагментом, но поочередно вы можете использовать df.join(..., how='inner', on='visit_id')
или how='left'
Вы необходимо предоставить минимальный воспроизводимый пример для вопросов, требующих помощи по отладке.
из вашего примера это выглядит как visits.visit_id> events.visit_id к 1670 году, поэтому вы должны ожидать, что events.visit_id будет в visits.visit_id и, таким образом, вернет все Trues?
@d_kennetz согласно документации: isin
Return a boolean Series showing whether each element in the Series matches an element in the passed sequence of values exactly.
Ваши correct_delta
и filter_real_v
похоже делают противоположные вещи? Я ожидаю, что correct_delta
будет больше соответствовать visits.visit_id.isin(events.visit_id)
.
@root, да, я облажался.
Все ведет себя правильно, вы просто неправильно интерпретируете операцию установки "-"
len(set(df_visits.visit_id) - set(df_events.visit_id))
Вернет значения df_visits.visit_id, которых нет в df_events.visit_id. Примечание: Если значения df_events.visit_id не находятся в df_visits.visit_id, они будут представлены здесь нет. Так работают наборы.
Например:
set([1,2,3,9]) - set([9,10,11])
Output:
{1, 2, 3}
Обратите внимание, что 10 или 11 не появляются в ответе. Ни один из второго набора не будет на самом деле. Только значения во втором наборе будут удалены из первого набора.
С isin()
вы эффективно делаете:
visits['visit_id'].isin(df_events['visit_id'].values).value_counts()
True 56071
False 1670
# Note 1670 is the exact same you got in your set operation
и нет:
df_events['visit_id'].isin(visits['visit_id'].values).value_counts()
True 702680
Ага, я запутался
А как же pd.DataFrame(df_events.visit_id).isin(real_visits)).visit_id.value_counts() #I get all False values except 8 that are True
pd.DataFrame(df_events.visit_id).isin(set(real_visits)).visit_id.value_counts() #I get all True values
Можете ли вы добавить фреймы данных здесь, в вопросе (я думаю, это не должно быть долго) вместо ссылки.