Панды: сравните огромный массив данных с меньшим - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть два кадра данных, которые я хочу сравнить в пандах: один слишком большой, чтобы уместиться в памяти, а другой меньше и умещается в памяти.

dfSmall:
cat1    cat2
foo     bar
foo     tiger
foo     spam
bar     spam
(5000 rows)

dfLarge:
cat1    cat2    cat3
foo     dog     green
foo     tiger   blue
foo     snake   green
foo     bird    pink
bar     dog     orange
...
(>1 million rows)

Я использовал dask.dataframe (dd.merge), но это занимает много времени и много хлопот, и кажется неэффективным, так как один из моих df влезет в память. Я также использовал pandas.read_table с установленным размером chunksize, но только для изменения самого файла, а не для сравнения его с другим файлом.

Дополнительным осложнением является то, что я хочу, чтобы в выходном файле содержались только строки, соответствующие двум столбцам - cat1 и cat2. В приведенном выше примере выводом будет всего одна строка - foo cat, потому что это единственная строка, в которой совпадают оба столбца. Если сопоставить два столбца невозможно, я не возражаю против решения, которое может соответствовать только одному столбцу, мне просто нужно изменить кадры данных, чтобы объединить cat1 / cat2 в один столбец.

dfOutput:
cat1    cat2    cat3
foo     tiger   blue

1 Ответ

0 голосов
/ 30 апреля 2018

Используя read_table с размером фрагмента , допустим, вы сначала создаете функцию, которая объединяет фрагмент с меньшей таблицей:

dfSmall = pd.read_table(small_path, ...)

def merge_it(c):
    return dfSmall.merge(c, on=['cat1', 'cat2'], suffixes=('', '_y'))[['cat1', 'cat2', 'cat3']]

Обратите внимание, что при слиянии панды добавят суффиксы к общим столбцам. Приведенный выше код говорит не добавлять суффиксы к столбцам фрагмента (то есть '' в кортеже) и брать столбцы 'cat1', 'cat2', 'cat3'.

Затем вы можете объединить куски слияния более крупных, например:

pd.concat([merge_it(c) for c in pd.read_table(large_path, ..., chunksize=100000)])

Обратите внимание, что для каждого чанка вы получаете его слияние с небольшим DataFrame. Чтобы получить полный результат, вам нужно объединить результаты.

...