Compter les index chez les pandas

8

Je pense que c'est une question rudimentaire, mais je suis très nouveau dans ce domaine et je n'ai tout simplement pas été en mesure de la résoudre / de trouver la réponse.

En fin de compte, ce que j'essaie de faire ici, c'est de compter les valeurs uniques sur une certaine colonne, puis de déterminer lesquelles de ces valeurs uniques ont plus d'une valeur unique dans une colonne correspondante.

Donc, pour ces données, ce que j'essaie de déterminer, c'est «qui» a «plus d'un reçu» pour tous les achats, puis déterminez les mêmes informations en fonction de chaque catégorie de produit.

Mon approche jusqu'à présent:

Nous avons un ensemble de données comme celui-ci:

receipt,name,etc,category
1,george,xxx,fish
1,george,xxx,cat
2,george,xxx,fish
3,bill,xxx,fish
3,bill,xxx,dog
4,jill,xxx,cat
5,bill,xxx,cat
5,bill,xxx,cat
5,bill,xxx,dog
6,george,xxx,fish

Alors je peux faire ça:

df.set_index(['name','receipt'])

Et obtenez le plus intéressant

                etc category
name   receipt
george 1        xxx     fish
       1        xxx      cat
       2        xxx     fish
bill   3        xxx     fish
       3        xxx      dog
jill   4        xxx      cat
bill   5        xxx      cat
       5        xxx      cat
       5        xxx      dog
george 6        xxx     fish

À ce stade, il me semble que les données sont faciles à utiliser, mais je ne l'ai pas compris.

Une chose qui m'intéresse est que si je trie les données par nom avant de les indexer, les données s'affichent groupées par nom. Dans les deux cas, l'index est le même, donc je ne sais pas comment jouer avec la représentation des données après l'indexation.

Il est facile de trouver les données par catégorie en utilisant

>>> orders.loc[orders['category'] == 'fish']
                etc category
name   receipt
george 1        xxx     fish
       2        xxx     fish
bill   3        xxx     fish
george 6        xxx     fish

Mais ce que je ne peux pas comprendre, c'est comment dire aux pandas "Trouvez-moi la liste des noms qui ont plus d'un reçu".

Questions plus petites:

  • Quelle est la «manière pandas» pour obtenir la longueur de la partie des noms de l'index? Je suppose que je pourrais simplement transformer la namecolonne en un ensemble et obtenir la longueur de cela. Mais je suis curieux de connaître les index.

Modifier / mettre à jour

Merci pour ces réponses! Voici des précisions sur ce que je recherche:

J'essaie de trouver des «clients réguliers»: des personnes avec plus d'un reçu.

Donc, mon ensemble de tous les clients serait:

names: ['george','bill','jill'], ratio: 1.0

Mes clients réguliers:

names: ['george','bill'], ratio 0.66

Tous les clients «poissons»:

names: ['george','bill'], ratio: 0.666

Mes clients fidèles «poissons»:

names: ['george'], ratio: 0.333

Je pense que les exemples donnés semblent utiles, mais n'hésitez pas à ajouter quoi que ce soit.

M. Hasquestions
la source
pouvez-vous publier un ensemble de données résultant souhaité (attendu)?
MaxU

Réponses:

5

Je pense que vous cherchez peut-être:

receipts_by_name_x_cat = df.groupby(['name','category']).count()

Ou, si vous voulez simplement le total dans toutes les catégories:

receipts_by_name = df.groupby(['name']).count()

Ensuite, vous pouvez rechercher ceux qui en ont plus d'un:

receipts_by_name[receipts_by_name['receipt']>1]

Et, vous pouvez trouver la longueur d'un index en tapant:

len(df.index.get_level_values(0))

En supposant que le nom était la première colonne d'index (sinon remplacez 1, 2, etc.)

atkat12
la source
C'est extrêmement utile. J'ai mal formulé ma question. "Plus d'un reçu" devrait être "Plus d'une transaction, ce qui signifie qu'ils ont plus d'un reçu unique ."
M. Hasquestions
Heureux de l'entendre. Re: votre question, en quoi les deux sont-ils différents? qu'est-ce qui définit un reçu unique - la colonne «reçu» est-elle l'identifiant du reçu? et la catégorie comprend tous les articles qu'ils ont achetés sur ce reçu? Si c'est le cas, vous pouvez essayer de receipts_by_name = df.groupby(['name']).unique()prendre la réponse dans la colonne «reçu», je pense. Il vous suffit d'appliquer une fonction de groupby différente.
atkat12
À droite, donc une façon de penser est que chaque ligne de l'ensemble de données représente un élément de ligne dans un achat, donc le reçu est "l'ID du reçu" de cette transaction. Ainsi, par exemple, Bill a acheté deux articles pour chats lors de la transaction # 5 et il est responsable de la transaction # 2. Il est donc un "acheteur répétitif" mais il n'est pas un "acheteur répétitif de chats" puisque ses deux achats de chats ont eu lieu au cours de la même transaction.
M. Hasquestions
3

On ne sait pas exactement ce que vous essayez d'atteindre (il serait utile de comprendre vos objectifs si vous publiez les ensembles de données souhaités / attendus) ...

Mais je vais essayer de deviner;)

Les données:

In [100]: df
Out[100]:
   receipt    name  etc category
0        1  george  xxx     fish
1        1  george  xxx      cat
2        2  george  xxx     fish
3        3    bill  xxx     fish
4        3    bill  xxx      dog
5        4    jill  xxx      cat
6        5    bill  xxx      cat
7        5    bill  xxx      cat
8        5    bill  xxx      dog
9        6  george  xxx     fish

Définition de la colonne virtuelle count, affichage du nombre de lignes regroupées nameet filtrage (interrogation) à l'aide de la .query()méthode:

In [101]: (df.assign(count=df.groupby('name').receipt.transform('size'))
     ...:    .query("category in ['dog','cat'] and count > 1"))
     ...:
Out[101]:
   receipt    name  etc category  count
1        1  george  xxx      cat      4
4        3    bill  xxx      dog      5
6        5    bill  xxx      cat      5
7        5    bill  xxx      cat      5
8        5    bill  xxx      dog      5

ou vous pouvez regrouper par plusieurs colonnes et filtrer les groupes résultants:

In [102]: df.groupby(['name','category']).filter(lambda x: len(x) > 2)
Out[102]:
   receipt    name  etc category
0        1  george  xxx     fish
2        2  george  xxx     fish
9        6  george  xxx     fish
MaxU
la source