1
votes

IndexError lors du remplacement des valeurs manquantes par le mode utilisant groupby dans les pandas

J'ai un ensemble de données qui nécessite un traitement des valeurs manquantes.

import pandas as pd
import numpy as np

data11=pd.DataFrame({'Complaint_ID':['Tr-1','Tr-2','Tr-3','Tr-4','Tr-5','Tr-6'],
                    'Transaction_Type':['Mortgage','Credit card','Bank account or service','Debt collection','Credit card','Mortgage'],
                    'Complaint_reason':['Loan servicing, payments, escrow account','Incorrect information on credit report',"Cont'd attempts collect debt not owed","Cont'd attempts collect debt not owed",'Payoff process','Loan servicing, payments, escrow account'],
                    'Company_response':[np.nan,'Company chooses not to provide a public response',np.nan,'Company believes it acted appropriately as authorized by contract or law','Company has responded to the consumer and the CFPB and chooses not to provide a public response','Company disputes the facts presented in the complaint'],
                    'Consumer_disputes':['Yes','No','No','No',np.nan,'Yes']})

data11.isnull().sum()

data11["Company_response"] = data11.groupby("Complaint_reason").transform(lambda x: x.fillna(x.mode()[0]))["Company_response"]
data11["Consumer_disputes"] = data11.groupby("Transaction_Type").transform(lambda x: x.fillna(x.mode()[0]))["Consumer_disputes"]    

Maintenant, le problème est que lorsque j'essaye de remplacer les valeurs manquantes par le mode d'un autre colonnes en utilisant groupby:

Code:

data11['Company_response'].fillna(data11['Company_response'].mode()[0], 
inplace=True)
data11['Consumer_disputes'].fillna(data11['Consumer_disputes'].mode()[0], 
inplace=True)

J'obtiens l'erreur suivante:

Stacktrace

Traceback (most recent call last):

File "<ipython-input-89-8de6a010a299>", line 1, in <module>
    data11["Company_response"] = data11.groupby("Complaint_reason").transform(lambda x: x.fillna(x.mode()[0]))["Company_response"]

  File "C:\Anaconda3\lib\site-packages\pandas\core\groupby.py", line 3741, in transform
    return self._transform_general(func, *args, **kwargs)

  File "C:\Anaconda3\lib\site-packages\pandas\core\groupby.py", line 3699, in _transform_general
    res = path(group)

  File "C:\Anaconda3\lib\site-packages\pandas\core\groupby.py", line 3783, in <lambda>
    lambda x: func(x, *args, **kwargs), axis=self.axis)

  File "C:\Anaconda3\lib\site-packages\pandas\core\frame.py", line 4360, in apply
    ignore_failures=ignore_failures)

  File "C:\Anaconda3\lib\site-packages\pandas\core\frame.py", line 4456, in _apply_standard
    results[i] = func(v)

  File "C:\Anaconda3\lib\site-packages\pandas\core\groupby.py", line 3783, in <lambda>
    lambda x: func(x, *args, **kwargs), axis=self.axis)

  File "<ipython-input-89-8de6a010a299>", line 1, in <lambda>
    data11["Company_response"] = data11.groupby("Complaint_reason").transform(lambda x: x.fillna(x.mode()[0]))["Company_response"]

  File "C:\Anaconda3\lib\site-packages\pandas\core\series.py", line 601, in __getitem__
    result = self.index.get_value(self, key)

  File "C:\Anaconda3\lib\site-packages\pandas\core\indexes\base.py", line 2434, in get_value
    return libts.get_value_box(s, key)

  File "pandas\_libs\tslib.pyx", line 923, in pandas._libs.tslib.get_value_box (pandas\_libs\tslib.c:18843)

  File "pandas\_libs\tslib.pyx", line 939, in pandas._libs.tslib.get_value_box (pandas\_libs\tslib.c:18560)

IndexError: ('index out of bounds', 'occurred at index Consumer_disputes')

J'ai vérifié la longueur du dataframe et toutes ses colonnes et c'est pareil : 43266.

J'ai également trouvé une question similaire à celle-ci mais je n'ai pas de réponse correcte: Cliquez ici

Veuillez aider à résoudre l'erreur.

IndexError: ('index out of bounds', 's'est produit à l'index Consumer_disputes')

Voici un aperçu de l'ensemble de données s'il est utile de quelque manière que ce soit: Dataset Snapshot

J'utilise le code ci-dessous avec succès. Mais cela ne sert pas exactement mon objectif. Aide à remplir les valeurs manquantes cependant.

data11["Company_response"] = 
data11.groupby("Complaint_reason").transform(lambda x: x.fillna(x.mode() 
[0]))["Company_response"]

data11["Consumer_disputes"] = 
data11.groupby("Transaction_Type").transform(lambda x: x.fillna(x.mode() 
[0]))["Consumer_disputes"]

Edit1: (Joindre un échantillon)

Entrée donnée: InputImage

Résultat attendu: OutputImage

Vous pouvez voir que les valeurs manquantes pour company-response de Tr-1 et Tr-3 sont remplies en prenant le mode Complaint-Reason. Et de même pour les litiges de consommation en prenant le mode de type transaction, pour Tr-5.

L'extrait ci-dessous comprend le dataframe et le code pour ceux qui veulent le répliquer et l'essayer.

Code de réplication

 Column                      Missing Values

 Complaint_ID                    0         
 Date_received                   0         
 Transaction_Type                0         
 Complaint_reason                0         
 Company_response              22506         
 Date_sent_to_company            0         
 Complaint_Status                0         
 Consumer_disputes             7698


10 commentaires

la question est littéralement morte la dernière fois, je l'ai éditée, laissé des commentaires mais personne n'a répondu pendant près de 6 jours, donc malheureusement j'ai dû la poster à nouveau car je n'ai pas de primes à offrir, donc les gars si vous le trouvez intéressant et que vous êtes incapable pour le résoudre, veuillez voter pour la question afin qu'elle puisse également intéresser les autres ...


Pourriez-vous ajouter un petit échantillon d'entrée et la sortie attendue


la question n'est pas «littéralement morte» - c'est une métaphore. il est mort au sens figuré!


@JoshFriedlander haha ​​... oui Josh ... s'est un peu emporté je suppose ...


:) quant à votre question - cela aiderait si vous pouviez publier comme 5 lignes de vos données, ou des équivalents inventés - cette capture d'écran est la bonne idée, mais le texte est beaucoup plus facile à travailler qu'une image


Je ne peux pas le reproduire. Pouvez-vous essayer d'appeler data11.groupby ("Complaint_reason"). Transform (lambda x: x.fillna (x.mode () [0])) ["Company_response"] (sans l'ajouter en tant que colonne) et voir quelle est sa forme?


@JoshFriedlander même erreur bro ...


Quelle version de pandas utilisez-vous? Améliorer les pandas? Je n'ai pas dupliqué votre erreur en donnant des données11 et une déclaration avec groupby.


@ScottBoston J'ai édité le code, maintenant vous serez en mesure de reproduire le problème, j'avais ealier mis dans une chaîne vide au lieu de nan. Pardon!! Et la version pandas est 0.20.1.


@JoshFriedlander, vous serez en mesure de reproduire le problème maintenant ... j'ai mis à jour le code ...


3 Réponses :


3
votes

L'erreur est générée car pour au moins un des groupes, les valeurs des colonnes agrégées correspondantes ne contiennent que des valeurs np.nan. Dans ce cas, pd.Series ([np.nan]). Mode () renvoie une série vide qui conduit à une erreur lorsque vous prenez la première valeur.

Donc, vous pouvez utiliser quelque chose comme transform (lambda x: x.fillna (x.mode () [0] sinon x.mode (). empty else "Empty")) .


8 commentaires

En exécutant cela, j'obtiens l'erreur exacte mentionnée dans la question. Mikhail pouvez-vous s'il vous plaît le répliquer sur votre local (j'ai donné le code dans la question pour la réplication), je suis vraiment coincé là-dessus depuis longtemps maintenant ..


Pourriez-vous fournir un stacktrace complet lorsque vous l'exécutez avec un code autonome pour créer des données d'entrée pour cela?


Mikhail J'ai mentionné le code autosuffisant avec entrée et le stacktrace dans la question elle-même.


Je voulais dire le stacktrace lorsque vous exécutez data11.groupby ("Transaction_Type"). Transform (lambda x: x.fillna (x.mode () [0])) . Je veux être sûr que c'est bien la même chose, ce qui est très peu probable. De plus, je n'ai pas trouvé d'extrait de code pour créer une trame de données d'entrée. Je ne peux pas le prendre à partir d'une capture d'écran d'un fichier Excel.


Mikhail s'il vous plaît observer attentivement j'ai mentionné le Code de réplication (en caractères gras sous les captures d'écran Excel) avec le dataframe d'entrée ... et le stacktrace que j'obtiens quand j'exécute data11.groupby ("Transaction_Type ") .transform (lambda x: x.fillna (x.mode () [0])) est très long, il ne peut pas être placé dans la section commentaires, alors laissez-moi mettre en évidence le stacktrace également dans la question elle-même dans gras. Remarque: le stacktrace est exactement le même pour le code que vous m'avez demandé d'exécuter.


Votre code commence par data11.isnull (). Sum () qui n'est pas défini ci-dessus.


Ok, j'ai corrigé la réponse


Merci pour les efforts Mikhail, mais quand je lance, data11 ["Company_response"] = data11.groupby ("Complaint_reason"). Transform (lambda x: x.fillna (x.mode () [0] sinon x.mode (). empty else "Vide")) data11 ["Consumer_disputes"] = data11.groupby ("Transaction_Type"). transform (lambda x: x.fillna (x.mode () [0] if not x. mode (). empty else "Empty")) , la colonne Consumer_disputes est foirée. La réponse de Scott a fait l'affaire pour moi. Mais merci pour tous les efforts :)



1
votes

Essayez :

data11["Company_response"] = data11.groupby("Complaint_reason")['Company_response'].transform(lambda x: x.fillna(x.mode()[0]))

data11["Consumer_disputes"] = data11.groupby("Transaction_Type")['Consumer_disputes'].transform(lambda x: x.fillna(x.mode()[0]))  


2 commentaires

Merci Scott ... :)


@AshuGrover De rien. Bon codage. Merci d'avoir modifié ma solution en fonction de vos besoins.



0
votes

@Mikhail Berlinkov a presque certainement raison. J'ai pu reproduire votre erreur, puis l'éviter en utilisant dropna():

data11.groupby("Transaction-Type").transform(
    lambda x: x.fillna(x.mode() [0]))["Consumer-disputes"]  
# Returns IndexError

data11.dropna().groupby("Transaction-Type").transform(
    lambda x: x.fillna(x.mode() [0]))["Consumer-disputes"]  
# Works


1 commentaires

Merci pour la contribution Josh, mais cela gâche encore plus le dataframe. Essayez-le par vous-même et voyez les résultats ...