2 votes

Veuillez traduire ceci en gardant les mêmes balises HTML s'il y en a : python pandas trier dans un groupe et appliquer une fonction

Supposons que j'ai le jeu de données iris. Existe-t-il un moyen d'effectuer de manière concise les opérations ci-dessous dans pandas ?

  1. Grouper par cible
  2. A l'intérieur de chaque groupe, arranger les données par "longueur du sépale (cm)" en ordre décroissant
  3. A l'intérieur de chaque groupe, attribuer 1 aux 5 premières lignes et 0 au reste ?

Pour ceux qui connaissent R, je veux simplement reproduire le code suivant (oui, c'était une solution de contournement là-bas) :

iris %>%
  group_by(Species) %>%
  arrange(desc(Sepal.Length)) %>%
  mutate(size_tag = 1,
         size_tag = cumsum(size_tag),
         size_tag = ifelse(size_tag <= 5, 1, 0))

Jusqu'à présent j'ai :

from sklearn import datasets
iris = datasets.load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                 columns= iris['feature_names'] + ['target'])

def fn(group, col_nm):
    group[col_nm] = 1
    group[col_nm] = np.cumsum(group[col_nm])
    group[col_nm] = np.where(group[col_nm] <= 5, 1, 0)
return group

iris['size_tag'] = np.NaN
iris.groupby('target').apply( pd.DataFrame.sort_values, 'sepal length (cm)' ).apply( fn, args = (['size_tag']))

Le résultat que j'obtiens est une ligne supplémentaire ajoutée au DataFrame...

Je débute tout juste avec pandas et Python, donc tout commentaire (par exemple, lié au style de codage) est le bienvenu.

2voto

piRSquared Points 159

Cela obtient la série de uns et de zéros

iris.sort_values(
    'sepal length (cm)', ascending=False
).groupby('target').cumcount().__floordiv__(5).eq(0).astype(np.uint8)

Plus lisible

s = iris.sort_values('sepal length (cm)', ascending=False)
c = s.groupby('target').cumcount()
((c // 5) == 0).astype(np.uint8)

Produire une copie avec une nouvelle colonne

s = iris.sort_values('sepal length (cm)', ascending=False)
c = s.groupby('target').cumcount()
top5 = ((c // 5) == 0).astype(np.uint8)
iris.assign(size_tag=top5)

entrer la description de l'image ici

1voto

AlexG Points 3695

J'ai reproduit votre dataframe R et je pense que cela fait la même chose :

iris = iris.sort_values(['target', 'sepal length (cm)'], ascending=False)
iris['size_tag'] = iris.index.isin(iris.groupby('target').head(5).index)*1

Nous trier d'abord les valeurs par l'espèce puis par la longueur du sépale dans chaque groupe d'espèces. Ensuite, nous ajoutons les étiquettes sur les 5 premières pour chaque groupe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X