Как объединить 2 кадра данных на основе сравнения? - PullRequest
2 голосов
/ 19 октября 2019

Предположим, у меня есть:

edu_data = [['school', 1, 2], ['college', 3, 4], ['grad-school', 5, 6]] 
edu = pd.DataFrame(edu_data, columns = ['Education', 'StudentID1', 'StudentID2']) 
print(edu)
     Education  StudentID1  StudentID2
0       school         1         2
1      college         3         4
2  grad-school         5         6

А потом у меня есть еще одна таблица с идентификаторами учеников:

data = [['tom', 3], ['nick', 5], ['juli', 6], ['jack', 10]] 
df = pd.DataFrame(data, columns = ['Name', 'StudentID']) 
print(df)
   Name  StudentID
0   tom        3
1  nick        5
2  juli        6
3  jack       10

Как мне получить таблицу, в которой я бы соответствовал df ['StudentID'] против edu ["StudentID1"] или edu ["StudentID2"]. Если df ['StudentID'] равен либо, то я хотел бы добавить edu ["Education"] к df.

Так что я ожидаю, что мой результат будет:

   Name  StudentID  Education
0   tom        3     college
1  nick        5     grad-school
2  juli        6     grad-school
3  jack       10     NaN

Ответы [ 4 ]

2 голосов
/ 19 октября 2019

Использование map

s = edu.set_index('Education').stack().reset_index(level=1, drop=True)

df['Education'] = df.StudentID.map(pd.Series(s.index, s.values))

   Name  StudentID    Education
0   tom          3      college
1  nick          5  grad-school
2  juli          6  grad-school
3  jack         10          NaN
2 голосов
/ 19 октября 2019

вы можете использовать DataFrame.melt:

mapper=edu.melt(id_vars='Education',var_name = 'StudentID',value_name='ID').set_index('ID')
df['Education']=df['StudentID'].map(mapper['Education'])
print(df)

   Name  StudentID    Education
0   tom          3      college
1  nick          5  grad-school
2  juli          6  grad-school
3  jack         10          NaN

Деталь:

print(mapper)

         Education   StudentID
ID                         
1           school  StudentID1
3          college  StudentID1
5      grad-school  StudentID1
2           school  StudentID2
4          college  StudentID2
6      grad-school  StudentID2

Также вы можете использовать Series.map + Series.combine_first:

eduID1=edu.set_index('StudentID1')
eduID2=edu.set_index('StudentID2')
df['Education']=df['StudentID'].map(eduID1['Education']).combine_first(df['StudentID'].map(eduID2['Education']))
print(df)

   Name  StudentID    Education
0   tom          3      college
1  nick          5  grad-school
2  juli          6  grad-school
3  jack         10          NaN
1 голос
/ 19 октября 2019

Использование карты, аналогично моему ответу ранее сегодня

mapper = edu.set_index('StudentID1')['Education'].to_dict()
mapper.update(edu.set_index('StudentID2')['Education'].to_dict())

df['Education'] = df['StudentID'].map(mapper)


    Name    StudentID   Education
0   tom     3           college
1   nick    5           grad-school
2   juli    6           grad-school
3   jack    10          NaN
1 голос
/ 19 октября 2019

Вот решение с melt и merge:

(df.merge(edu.melt(id_vars='Education', 
                  value_name='StudentID'),
         on='StudentID',
         how='left')     
      .drop_duplicates(['Name','StudentID'])    # this is for when both StudentID match, we choose the first
     .drop('variable', axis=1)
)

Вывод:

   Name  StudentID    Education
0   tom          3      college
1  nick          5  grad-school
2  juli          6  grad-school
3  jack         10          NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...