2017-10-13 8 views
2

Je voudrais que le dataframe passé dans cette fonction à modifier.Comment assigner la variable à dataframe Pandas fusionnée au sein de la fonction

def func(df): 
    left_df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B']) 
    right_df = pd.DataFrame([[5, 6], [7, 8]], columns=['C', 'D']) 
    df = pd.merge(left_df, right_df, how='outer', left_index=True, right_index=True) 
    print("df is now a merged dataframe!") 

test = pd.DataFrame() 
func(test) 

Cependant, depuis Python passe par la valeur, le func() obtient une callee copie de df qui pointe vers le dataframe vide d'origine. Quand il est affecté à la trame de données fusionnée, il crée un nouvel objet retourné par pd.merge() et des points df à ce nouvel objet. Cependant, test est inchangé et continue de pointer vers la trame de données vide d'origine.

Comment peut-on fusionner en place dans func() alors test est actuellement modifié? Je voudrais quelque chose comme pandas.DataFrame.update(), mais cela ne vous permet que de faire des jointures à gauche.

Répondre

1

IIUC, quelque chose comme ça?

def func(df): 
    left_df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B']) 
    right_df = pd.DataFrame([[5, 6], [7, 8]], columns=['C', 'D']) 
    df = pd.merge(left_df, right_df, how='outer', left_index=True, right_index=True) 
    print("df is now a merged dataframe!") 
    global test 
    test = df 

test = pd.DataFrame() 
func(test) 
print(test) 

Sortie:

df is now a merged dataframe! 
    A B C D 
0 1 2 5 6 
1 3 4 7 8 
+0

Cela fonctionne vraiment! Selon [ce poste] (https://stackoverflow.com/questions/38895768/python-pandas-dataframe-is-it-pass-by-value-or-pass-by-reference), en utilisant des variables globales peut rendre difficile de savoir où les changements se sont produits, mais c'est la meilleure solution que j'ai vu. – haudarren

1

Python ne passe pas par la valeur!
NOTE: Ce est une mauvaise pratique de codage en général
PROOF

test = pd.DataFrame([[1, 2], [3, 4]]) 

def func(df): 
    df.loc[:] = df * 2 

print(test) 
func(test) 
print(test) 

    0 1 
0 1 2 
1 3 4 

    0 1 
0 2 4 
1 6 8 

Votre problème est que vous nommez une version locale du nom df. Vous devez modifier la trame de données inplace en quelque sorte.

test = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB')) 

def func(df): 
    df.loc[:, 'C'] = 9 

print(test) 
func(test) 
print(test) 

    A B 
0 1 2 
1 3 4 

    A B C 
0 1 2 9 
1 3 4 9