у меня есть два dfs
df1 = pd.DataFrame({'pupil': ["sarah", "john", "fred"],
'class': ["1a", "1a", "1a"]})
df2 = pd.DataFrame({'pupil_mixed': ["sarah", "john", "lex"],
'class': ["1a", "1c", "1a"]})
Я хочу добавить значения строки из столбца «pupil_mixed» из df2 в столбец «ученик» в df1, если значения не дублируются
желаемый результат:
df1 = pd.DataFrame({'pupil': ["sarah", "john", "fred", 'lex'],
'class': ["1a", "1a", "1a", NaN]})
Я использовал append
с loc
df1 = df1.append(df2.loc[df2['pupil_mixed'] != df1['pupil'] ])
который просто добавил другой столбец в df с соответствующим значением строки и изменил несоответствующие значения строки на NaN
pupil class pupil_mixed
0 sarah 1a NaN
1 john 1a NaN
2 fred 1a NaN
2 NaN 1a lex
Вы можете использовать concat + drop_duplicates:
res = pd.concat((df1, df2['pupil_mixed'].to_frame('pupil'))).drop_duplicates('pupil')
print(res)
Выход
pupil class
0 sarah 1a
1 john 1a
2 fred 1a
2 lex NaN
В качестве альтернативы вы можете сначала отфильтровать (с помощью isin), а затем объединить:
# filter the rows in df2, rename the column pupil_mixed
filtered = df2.loc[~df2['pupil_mixed'].isin(df1['pupil'])]
# create a new single column DataFrame with the pupil column
res = pd.concat((df1, filtered['pupil_mixed'].to_frame('pupil')))
print(res)
В обоих решениях используется to_frame с параметром имени, эффективно меняющим имя столбца.
# distinct df1 & df2
df1['tag'] = 1
df2['tag'] = 2
# change the column name the same
df2.columns = df1.columns
df1 = df1.append(df2)
# drop_duplicates by keep df1
df1 = df1.drop_duplicates('pupil', keep='first')
# set tag == 2, class is null
cond = df1['tag'] == 2
df1.loc[cond, 'class'] = np.nan
del df1['tag']
print(df1)
выход:
print(df1)
pupil class
0 sarah 1a
1 john 1a
2 fred 1a
3 lex NaN
Вы можете использовать слияние после переименования pupil_mixed
в df2:
df1.merge(df2["pupil_mixed"].rename("pupil"), how = "outer")
pupil class
0 sarah 1a
1 john 1a
2 fred 1a
3 lex NaN
Почему класс для Лекса
NaN
?