J'ai un df
qui contient mes données principales qui a un million rows
. Mes données principales ont également 30 columns
. Maintenant, je veux ajouter une autre colonne à ma df
appelée category
. La category
est une column
dans df2
qui contient environ 700 rows
et deux autres columns
qui correspondront à deux columns
dans df
.
Je commence par définir une index
dans df2
et df
qui correspondra entre les trames, mais certaines des index
dans df2
n'existent pas dans df
.
Les colonnes restantes dans df2
s'appellent AUTHOR_NAME
et CATEGORY
.
La colonne correspondante dans df
s'appelle AUTHOR_NAME
.
Une partie du AUTHOR_NAME
dans df
n'existe pas dans df2
et vice versa.
L'instruction que je veux est la suivante: quand index
dans df
correspond à index
dans df2
et title
dans df
correspond à title
dans df2
, ajoutez category
à df
, sinon ajoutez NaN dans category
.
Exemple de données:
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
Si j'utilise df2.merge(df,left_index=True,right_index=True,how='left', on=['AUTHOR_NAME'])
, ma df
devient trois fois plus grande que ce qu'elle est censée être.
J'ai donc pensé que fusionner était peut-être la mauvaise façon de procéder. Ce que j'essaie vraiment de faire est d'utiliser df2
comme table de consultation, puis de renvoyer les valeurs type
à df
en fonction de certaines conditions.
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)
Cependant, cela me jette une erreur:
IndexError: ('index out of bounds', u'occurred at index 7614')
Considérez les images suivantes df
et 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')
))
Option 1merge
df.merge(df2, how='left')
Option 2join
cols = ['AUTHOR_NAME', 'title']
df.join(df2.set_index(cols), on=cols)
les deux options donnent
APPROCHE 1:
Vous pouvez utiliser concat
à la place et supprimer les valeurs dupliquées présentes dans les colonnes Index
et AUTHOR_NAME
combinées. Après cela, utilisez isin
pour vérifier l’adhésion:
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)]
Remarque: La colonne Index
est supposée être définie comme colonne d'index pour le DF's
.
APPROCHE 2:
Utilisez join
après avoir défini la colonne d'index correctement, comme indiqué:
df2.set_index(['Index', 'AUTHOR_NAME'], inplace=True)
df.set_index(['Index', 'AUTHOR_NAME'], inplace=True)
df.join(df2).reset_index()
Alors que les autres réponses ici donnent des solutions très bonnes et élégantes à la question posée, j’ai trouvé une ressource qui répond à la fois de manière extrêmement élégante à cette question, ainsi que des exemples joliment clairs et simples sur la manière de réaliser rejoindre fusion de trames de données et enseignement efficace des jointures LEFT, RIGHT, INNER et EXTER.
Joindre et fusionner un cadre de données Pandas
Honnêtement, j’ai le sentiment que tout chercheur après ce sujet voudra également examiner ses exemples ...