Проверка наличия списка в другом списке
Подскажите пожалуйста, что не правильно работает в функции ниже?
if len(in_db_not_existed) > 0:
for i in dataframe.values:
print("*******")
print(i)
print(in_db_not_existed.values)
print("*******")
if i in in_db_not_existed.values:
print(True)
in_db_not_existed.values и i это numpy.ndarray которые выглядят примерно так:
in_db_not_existed = pd.DataFrame([["Timestamp('2023-05-05 00:00:00')", "150200117","ПУШКИНО_1_РФЦ"], \
["Timestamp('2023-05-05 00:00:00')", "862471210", "Казань_РФЦ_НОВЫЙ"]])
print(in_db_not_existed.values)
dataframe = pd.DataFrame([["Timestamp('2023-05-05 00:00:00')", "862329540" "Санкт_Петербург_РФЦ"], \
["Timestamp('2023-05-05 00:00:00')", "832964666", "Казань_РФЦ_НОВЫЙ"], \
["Timestamp('2023-05-05 00:00:00')", "832963639", "САМАРА_РФЦ"], \
["Timestamp('2023-05-05 00:00:00')", "832963639", "ЖУКОВСКИЙ_РФЦ"], \
["Timestamp('2023-05-05 00:00:00')", "150200117","ПУШКИНО_1_РФЦ"], \
["Timestamp('2023-05-05 00:00:00')", "862471210", "Казань_РФЦ_НОВЫЙ"]])
print(dataframe.values)
Мною ожидается что в цикле каждое значение из dataframe.values провериться на наличие в in_db_not_existed.values и выдаст True если есть, но почему True срабатывает всегда, как это можно решить?
Ответы (1 шт):
При сравнении (многоуровневого) массива, numpy использует поэлементный подход any - то есть, если какой-то элемент подсписка равен какому-то элементу другого подсписка, вы получите True. В вашем примере всегда есть совпадение значения Timestamp. Попробуйте изменить в in_db_not_existed в элементе Timestamp секунды и запустите ваш код - теперь True будет только у некоторых элементов (потому что совпадают какие-то другие поля). Для эксплицитного сравнения "все равны всем", можете попробовать явно использовать метод all (как здесь, например).
Что вы хотите выяснить? Есть ли строки из dataframe в in_db_not_existed? Если да, тогда зачем такое сложноe решение? и вообще, грех пользоваться циклами, если у вас есть весь инструментарий pandas:
res = pd.merge(dataframe, in_db_not_existed, how ='inner')
res:
0 1 2
0 Timestamp('2023-05-05 00:00:00') 150200117 ПУШКИНО_1_РФЦ
1 Timestamp('2023-05-05 00:00:00') 862471210 Казань_РФЦ_НОВЫЙ
это решение покажет вам пересечение ваших датафреймов, то есть те строки, которые есть в обоих. Если, как выяснилось, у вас нужно найти частичное совпадение (в одном фрейме содрержатся все поля друого фрема плюс что-то еще), то можно включить в merge параметр on, где указать список нужных столбцов.