Je travaille sur un problème où j'utilise un groupby.apply imbriqué sur un pandas DataFrame. Pendant la première application, j'ajoute une colonne que j'utilise pour le deuxième groupby.apply interne. Le résultat combiné me semble défectueux. Quelqu'un peut-il m'expliquer pourquoi les phénomènes ci-dessous se produisent et comment y remédier de manière fiable?
Voici un exemple minimal:
import numpy as np
import pandas as pd
T = np.array( [
[1,1,1],
[1,1,1],
[1,2,2],
[1,2,2],
[2,1,3],
[2,1,3],
[2,2,4],
[2,2,4],
])
df = pd.DataFrame(T, columns= ['a','b','c' ])
print(df)
def foo2(x):
return x
def foo(x):
print("*" * 80 )
# Add column d and groupby/apply on column 'd'
x['d'] = [1, 1, 2, 2]
x = x.groupby('d').apply(foo2)
print(x)
print("*" * 80)
return x
# Apply first groupby/apply on column 'a'
df = df.groupby('a').apply( foo)
print("*"*80)
print("*"*80)
print(df)
Lorsque j'exécute le code ci-dessus sur mon ordinateur portable Windows, j'obtiens le résultat attendu
a b c d
a
1 0 1 1 1 1
1 1 1 1 1
2 1 2 2 2
3 1 2 2 2
2 4 2 1 3 1
5 2 1 3 1
6 2 2 4 2
7 2 2 4 2
Exécuter le même code sur un Mac donne
a b c d
a
1 0 1 1 1 1
1 1 1 1 1
2 1 2 2 2
3 1 2 2 2
2 4 1 1 3 1
5 1 1 3 1
6 1 2 4 2
7 1 2 4 2
Le problème ici est que dans la colonne «a», les 4 dernières entrées sont 1 alors qu'elles devraient être 2 comme sur la machine Windows.
ÉDITER:
Version Pandas sur les deux: 0.24.2
Version Python sous Windows: 3.7.3
Version Python sur Mac: 3.7.4
[Mac, Python: 3.6.8]
Je pense que le comportement attendu des DataFrame.apply
s imbriqués va être un peu compliqué à déboguer. Ma recommandation est d'aller droit au but en émulant ce que vous voulez réaliser apply
(c'est-à-dire cartographier puis réduire):
map
méthode native de python , suivie depandas.concat
pour combiner les résultatsimport numpy as np
import pandas as pd
def my_apply(df, f):
return pd.concat(map(f, df))
def foo(x):
group, grouped = x
grouped['d'] = [1, 1, 2, 2]
return grouped.groupby('d').apply(lambda x: x)
T = np.array([[1,1,1]]*2 + [[1,2,2]]*2 +
[[2,1,3]]*2 + [[2,2,4]]*2)
df = pd.DataFrame(T, columns= ['a','b','c' ])
df = my_apply(df.groupby('a'), foo)
print(df)
Résultat:
a b c d
0 1 1 1 1
1 1 1 1 1
2 1 2 2 2
3 1 2 2 2
4 2 1 3 1
5 2 1 3 1
6 2 2 4 2
7 2 2 4 2
Remarques:
foo2
par un lambda
, n'hésitez pas à revenir en arrière.A value is trying to be set on a copy of a slice from a DataFrame [...]
. C'est parce que nous définissons délibérément la valeur d'une copie. C'est un comportement attendu, pas un bogue. pandas
Cette opération interprète malheureusement cette opération comme une erreur, car elle l'est probablement normalement.Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots