Как бы я сделал пользовательское слияние с панелями данных? - PullRequest
3 голосов
/ 18 октября 2019

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

data = [['tom', 10, 20], ['nick', 15, 30], ['juli', 14, 40]] 
df = pd.DataFrame(data, columns = ['Name', 'Low-Age', 'High-Age']) 
print(df)
None
   Name  Low-Age  High-Age
0   tom       10        20
1  nick       15        30
2  juli       14        40

А затем у меня есть еще одна таблица:

data = [[10, 'school'], [30, 'college']] 
edu = pd.DataFrame(data, columns = ['Age', 'Education']) 
print(edu)
None
   Age Education
0   10    school
1   30   college

Как мне получить таблицу, в которой я бы сопоставил edu ['Age'] с любым из них? df ["Low-Age"] или df ["High-Age"]. Если они совпадают, я бы хотел добавить edu ["Education"] в df. (предположим, что у младшего или старшего возраста могут быть совпадения, а НЕ оба)

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

  Name  Low-Age  High-Age   Education
0   tom       10        20    school
1  nick       15        30    college
2  juli       14        40     NaN

Ответы [ 4 ]

4 голосов
/ 18 октября 2019

stack -> map

edu_dict = dict(zip(edu.Age, edu.Education))

Education = df[['Low-Age', 'High-Age']].stack().map(edu_dict).groupby(level=0).first()
df.assign(Education=Education)

   Name  Low-Age  High-Age Education
0   tom       10        20    school
1  nick       15        30   college
2  juli       14        40       NaN
3 голосов
/ 18 октября 2019

Использовать карту с comb_first

mapper = edu.set_index('Age')['Education']
df['Education'] = df['Low-Age'].map(mapper).combine_first(df['High-Age'].map(mapper))

    Name    Low-Age High-Age    Education
0   tom     10      20          school
1   nick    15      30          college
2   juli    14      40          NaN
2 голосов
/ 18 октября 2019

Использование Series.map + pd.concat:

edu2=edu.set_index('Age')
s=pd.concat([df['Low-Age'].map(edu2['Education']),df['High-Age'].map(edu2['Education'])])
df['Education']=s[s.notna()].reindex(index=df.index)
print(df)

   Name  Low-Age  High-Age Education
0   tom       10        20    school
1  nick       15        30   college
2  juli       14        40       NaN

Также вы можете суммировать вместо pd.concat :

edu2=edu.set_index('Age')
df['Education']= ( df['High-Age'].map(edu2['Education']).fillna('')+
                  df['Low-Age'].map(edu2['Education']).fillna('') )

или

edu2=edu.set_index('Age')
df['Education']= df[['High-Age','Low-Age']].apply(lambda x: x.map(edu2['Education']).fillna('')).sum(axis=1)

print(df)

   Name  Low-Age  High-Age Education
0   tom       10        20    school
1  nick       15        30   college
2  juli       14        40          
1 голос
/ 18 октября 2019

Этот подход дает вам результаты за меньшее время при работе с большими наборами данных. apply () используется.

low_age_list = df['Low-Age'].tolist()
high_age_list = df['High-Age'].tolist()

def match(row):
   print(row[1])
      if row['Age'] in low_age_list or row['Age'] in high_age_list:
         return row[1]

df['Education'] = edu.apply(match,axis=1)
print(df)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...