Pandas - Объединить один кадр данных с собой только частично - PullRequest
0 голосов
/ 17 января 2020

Это дополнительный вопрос из следующего Вопроса: Pandas Соответствие сходства

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

Вот пример кадра данных:

 df = pd.DataFrame([[1, 5, 'AADDEEEEIILMNORRTU'], [2, 5, 'AACEEEEGMMNNTT'], [3, 5, 'AAACCCCEFHIILMNNOPRRRSSTTUUY'], [4, 5, 'DEEEGINOOPRRSTY'], [5, 5, 'AACCDEEHHIIKMNNNNTTW'], [6, 5, 'ACEEHHIKMMNSSTUV'], [7, 5, 'ACELMNOOPPRRTU'], [8, 5, 'BIT'], [9, 5, 'APR'], [10, 5, 'CDEEEGHILLLNOOST'], [11, 5, 'ACCMNO'], [12, 5, 'AIK'], [13, 5, 'CCHHLLOORSSSTTUZ'], [14, 5, 'ANNOSXY'], [15, 5, 'AABBCEEEEHIILMNNOPRRRSSTUUVY']],columns=['PartnerId','CountryId','Name'])

Ответ в другом потоке был хорош для вопроса, но я в итоге получил вычислительные проблемы. Мой реальный источник содержит> 19 000 строк и будет еще больше в будущем.

В ответе предлагается merge датафрейм для каждого себя, чтобы сравнить его с каждой другой строкой, имеющей такой же CountryId:

df = df.merge(df, on='CountryId', how='outer')  

Даже для небольшого примера из 15 строк, представленного выше, мы получим 225 объединенных строк. Для всего набора данных у меня было 131.044.638 строк, из-за чего ОЗУ отказывалось работать. Поэтому мне нужно подумать о лучшем способе merge двух фреймов данных.

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

  1. Сортировка кадра данных по CountryId и Name

  2. Объединять только каждую строку с соединением +/- 3 строки. Например, после сортировки строка 1 будет объединена только с (2,3 и 4), поскольку это первая строка. Строка 2 будет объединена только с (1, 3, 4, 5) и т. Д.

Таким образом, у меня будут похожие имена почти рядом друг с другом, а имена "подальше" все равно не будут похожими. Поэтому нет необходимости проверять их сходство.

1 Ответ

0 голосов
/ 17 января 2020

Я нашел обходной путь для моей проблемы, который состоит из 3 строк до (если есть) и после.

sorted_df = df.sort_values(by=['CountryId','Name']).reset_index(drop=True)
new_sorted = pd.Series()
min = -3
max = 3
for s in list(range(min,max+1,1)):
    if s == min:
        new_sorted = sorted_df['PartnerId'].astype(str).shift(s,fill_value='A').rename('MatchingID')
    elif s != 0:
        new_sorted = new_sorted + '-' + sorted_df['PartnerId'].astype(str).shift(s,fill_value='A').rename('MatchingID')


match = sorted_df.merge(new_sorted,left_index=True,right_index=True)

matching_df = []
for index, row in match.iterrows():
    row_values = row.tolist()
    matching_df += [row_values[0:-1] + [int(w)] for w in row_values[-1].split('-') if w != 'A']

Если кто-нибудь может предложить лучшую идею, я буду рад ее услышать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...