Проверка наличия списка в другом списке

Рейтинг: 1Ответов: 1Опубликовано: 05.05.2023

Подскажите пожалуйста, что не правильно работает в функции ниже?

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, где указать список нужных столбцов.