Какой самый быстрый способ узнать, совпадают ли значения в пустом OrderedDict в другом OrderedDict? - PullRequest
1 голос
/ 24 апреля 2019

Я пытаюсь определить, являются ли два значения, содержащиеся в разных объектах numpy orderdict, одинаковыми.

Оба словаря были созданы с помощью опции fetchallnumpy() в turbodbc и состоят из двух ключей.Первый ключ - это поле id, второй ключ - строковое значение переменной длины.Я хочу посмотреть, присутствует ли строковое значение в первом наборе элементов словаря во втором наборе элементов словаря.

Вероятно, стоит отметить, что оба объекта словаря содержат приблизительно 60 миллионов значений под каждым ключом.

Я уже пробовал несколько вещей: -

  1. np.isin(dict1[str_col],dict2[str_col])

    Как функция, но это было чрезвычайномедленно, предположительно, потому что строковые значения хранятся как dtype объект.

  2. Я пытался преобразовать оба объекта с диктационными значениями в numpy массивы с явным строковым типом как np.asarray(dict1[str_col], dtype='S500')затем попытался использовать функции isin и in1d.В этот момент системе не хватает оперативной памяти.Поменял S500 на dtype=np.string_, но все равно получил MemoryError.(ar=np.concatenate((ar1,ar2))) при выполнении функции isin.

  3. Я также попробовал цикл for.

    [r in dict2[str_col] for r in dict1[str_col]]

    Опять же, это было очень медленно.

Моя цель - сравнительно быстрый способ тестирования двух струн.столбцы без исчерпания памяти.

Дополнительные биты В долгосрочной перспективе я буду выполнять более одной проверки, поскольку я пытаюсь определить> новые значения и значения, которыебыли изменены.

Словарь A = Текущие данные ['ID': [int, int, int]] Словарь B = Исторические данные ['record': [str, str, str]]

Так чтоИнтересующие меня биты: -

  • A! = B (текущая запись отличается от исторической записи)
  • A отсутствует в B (новая запись добавлена ​​в базу данных)
  • B отсутствует в A (записи должны быть отредактированы)

Последние два элемента, самый быстрый способ, который я обнаружил, - это передача столбцов id в функциюкоторый содержит np.isin (arr1, arr2).Сравнивает данные в среднем 15 секунд.

Ответы [ 2 ]

0 голосов
/ 24 апреля 2019

До сих пор не совсем ясно, чего вы пытаетесь достичь (см. Мои комментарии).Но вот мой короткий.

Pandas может предложить более эффективную альтернативу для сравнения списков строк.Сам не проверял это на больших порциях данных.

Попробуйте следующее:

import pandas as pd
s1 = pd.Series(dict1[str_col])
s2 = pd.Series(dict2[str_col])
print(s1.isin(s2).all())

Или, если вам в любом случае нужно перебрать все столбцы, вы можете преобразовать полные словари вdataframe:

df1 = pd.DataFrame(dict1)
df2 = pd.DataFrame(dict2)
for col in df1:
    print(df1[col].isin(df2[col]).all())

Если вы хотите проверить на равенство полного DataFrame, вы можете использовать pandas 'assert_frame_equal.Например:

 pd.util.testing.assert_frame_equal(df1, df2)     
 # ...or if the ordering is not the same.
 pd.util.testing.assert_frame_equal(df1, df2, check_like=True)

По-видимому, существует возможность прямого сброса данных turbodbc в объект pandas (to_pandas()).Смотрите здесь: документация на turbodbc, расширенное использование

0 голосов
/ 24 апреля 2019

Вы можете использовать np.searchsorted для более быстрого поиска:

ar1 = dict1[str_col]
ar2 = dict2[str_col]
sorter = np.argsort(ar2)
idx = np.searchsorted(ar2, ar1, sorter=sorter)
if idx.max() >= len(ar2):
    return False
return np.all(ar1 == ar2[sorter[idx]])
...