2017-04-23 2 views
2

J'ai deux dataframes:vectorisé dataframe consultation

df = pd.DataFrame([['A', 'B'], ['B', 'A']], columns=['Mon', 'Tues']) 

    Mon Tues 
0 A B 
1 B A 

lookup = pd.DataFrame([[0, 1], [2, 3]], index=['A', 'B'], columns=df.columns) 

    Mon Tues 
A 0 1 
B 2 3 

Pour chaque jour, pour chaque clé dans la première trame de données, je voudrais regarder sa valeur dans la seconde trame de données. C'est une façon de le faire:

output = pd.DataFrame() 
for col in df.columns: 
    output[col] = df[col].map(lookup[col]) 

    Mon Tues 
0 0 3 
1 2 1 

Existe-t-il un moyen d'obtenir la même réponse sans la boucle explicite?

Répondre

3

Vous pouvez utiliser replace d'échanger les valeurs:

>>> df.replace(lookup) 
    Mon Tues 
0 0  3 
1 2  1 

Lorsqu'il est passé à la méthode replace, DataFrames sont traités de façon similaire à des dictionnaires imbriqués. Pour chaque étiquette de colonne, les valeurs de la colonne sont mappées à la valeur indexée en conséquence dans la structure DataFrame de référence.

2

Je suppose que chaque donnée de colonne dans df est un ordre aléatoire du lookup.index et que lookup.index est dans l'ordre trié. Donc, aller avec elle, voici une solution vectorisé basée NumPy, en particulier en utilisant son advanced-indexing -

idx = np.argsort(df.values,1) 
df_out = pd.DataFrame(lookup.values[idx,np.arange(idx.shape[1])],columns=df.columns) 

Exemple de sortie -

In [41]: idx = np.argsort(df.values,1) 

In [42]: pd.DataFrame(lookup.values[idx,np.arange(idx.shape[1])],columns=df.columns) 
Out[42]: 
    Mon Tues 
0 0  3 
1 2  1 

Si lookup.index est pas dans l'ordre de tri, nous devons faire des travaux supplémentaires -

sidx = lookup.index.argsort() 
arr_out = lookup.values[idx,np.arange(idx.shape[1])][sidx]