Pandas заполняет новый столбец данных на основе совпадающих столбцов в другом фрейме данных

У меня есть df, который содержит мои основные данные, у которого есть миллион rows. Мои основные данные также имеют 30 columns. Теперь я хочу добавить еще один столбец в мой df, называемый category. category является column в df2, который содержит около 700 rows и еще два columns, которые будут совпадать с двумя columns в df.

Я начинаю с установки index в df2 и df, которая будет соответствовать между кадрами, однако некоторые из index в df2 не существуют в df.

Остальные столбцы в df2 называются AUTHOR_NAME и category.

Соответствующий столбец в df называется AUTHOR_NAME.

Некоторые из AUTHOR_NAME в df не существуют в df2 и наоборот.

Мне нужна инструкция: когда index в df соответствует index в df2 и title в df соответствует title в df2, добавьте category в df, иначе добавьте NaN в category.

Пример данных:

df2
           AUTHOR_NAME              CATEGORY
Index       
Pub1        author1                 main
Pub2        author1                 main
Pub3        author1                 main
Pub1        author2                 sub
Pub3        author2                 sub
Pub2        author4                 sub


df
            AUTHOR_NAME     ...n amount of other columns        
Index       
Pub1        author1                 
Pub2        author1     
Pub1        author2 
Pub1        author3
Pub2        author4 

expected_result
            AUTHOR_NAME             CATEGORY   ...n amount of other columns
Index
Pub1        author1                 main
Pub2        author1                 main
Pub1        author2                 sub
Pub1        author3                 NaN
Pub2        author4                 sub

Если я использую df2.merge(df,left_index=True,right_index=True,how='left', on=['AUTHOR_NAME']), мой df будет в три раза больше, чем предполагается.

Поэтому я думал, что слияние было неправильным способом. То, что я действительно пытаюсь сделать, это использовать df2 в качестве таблицы поиска, а затем вернуть значения type в df в зависимости от того, выполняются ли определенные условия.

def calculate_category(df2, d):
    category_row = df2[(df2["Index"] == d["Index"]) & (df2["AUTHOR_NAME"] == d["AUTHOR_NAME"])]
    return str(category_row['CATEGORY'].iat[0])

df.apply(lambda d: calculate_category(df2, d), axis=1)

Однако это вызывает ошибку:

IndexError: ('index out of bounds', u'occurred at index 7614')

Ответ 1

Рассмотрим следующие файлы данных df и df2

df = pd.DataFrame(dict(
        AUTHOR_NAME=list('AAABBCCCCDEEFGG'),
        title=      list('zyxwvutsrqponml')
    ))

df2 = pd.DataFrame(dict(
        AUTHOR_NAME=list('AABCCEGG'),
        title      =list('zwvtrpml'),
        CATEGORY   =list('11223344')
    ))

вариант 1
merge

df.merge(df2, how='left')

вариант 2
join

cols = ['AUTHOR_NAME', 'title']
df.join(df2.set_index(cols), on=cols)

оба параметра дают

введите описание изображения здесь

Ответ 2

ПОДХОД 1:

Вместо этого вы можете использовать concat и сбросить дублированные значения, присутствующие в столбцах Index и AUTHOR_NAME, вместе взятых. После этого используйте isin для проверки членства:

df_concat = pd.concat([df2, df]).reset_index().drop_duplicates(['Index', 'AUTHOR_NAME'])
df_concat.set_index('Index', inplace=True)
df_concat[df_concat.index.isin(df.index)]

Изображение

Примечание. Столбец Index предполагается установленным как столбец индекса для DF's.


ПОДХОД 2:

Используйте join после правильной установки столбца индекса, как показано:

df2.set_index(['Index', 'AUTHOR_NAME'], inplace=True)
df.set_index(['Index', 'AUTHOR_NAME'], inplace=True)

df.join(df2).reset_index()

Изображение

Ответ 3

В то время как другие ответы здесь дают очень хорошие и изящные решения заданного вопроса, я нашел ресурс, который оба отвечает на этот вопрос чрезвычайно изящным способом, а также дает красиво ясный и простой набор примеров того, как выполнить соединение/объединение фреймов данных, эффективно обучающее соединения LEFT, RIGHT, INNER и OUTER.

Объединяйте и объединяйте Pandas Dataframe

Я, честно говоря, чувствую, что дальнейшие искатели после этой темы захотят также изучить его примеры...

Ответ 4

Вы можете попробовать следующее. Он объединит оба набора данных в указанном столбце в качестве ключа.

expected_result = pd.merge(df, df2, on = 'CATEGORY', how = 'left')

Ответ 5

Пытаться

df = df.combine_first(df2)