1
votes

Application simultanée de la fonction Pandas aux lignes et aux colonnes pour les calculs d'intervalle de confiance

Je suis nouveau dans la programmation python. J'essaie de déterminer les valeurs aberrantes dans mon ensemble de données. J'ai converti l'ensemble de données en une trame de données pandas, puis j'ai appliqué le principe IQR. Après cela, je veux remplacer mes OUTLIERS par zéro, puis calculer la moyenne et l'écart type comme valeurs aberrantes en biaisant la moyenne et l'écart-type.


Le code de l'ensemble de données est le suivant:

Desired Result:
ID  Store1  Store2  Store3  Min Max Lower_Limit Upper_limit
123 100    1200     800     800 1200    900      1400
246 15     16       45      15  45      11       55
234 0      105      180     90  180    100       220
236 100    90       0       90  9000    70       140

Extrait de l'ensemble de données:

    ID  Store1 Store2 Store3(Store1 Store2 Store3)
ID                  
123 NaN NaN NaN NaN 1000
246 NaN NaN NaN NaN 15
234 NaN NaN NaN NaN 0
236 NaN NaN NaN NaN 0

Je souhaite mettre à jour les valeurs de Store1, Store2, Store3 à ZERO (0) si elles sont inférieures que Lower_limit (['Store1'] ['Upper_limit']).


Voici ma fonction: p>

df['Store1','Store3','Store3'] = df.apply(calculate_Outliers, axis=1)

Je l'applique comme ceci:

def calculate_Outliers(row):
    if row['Store1'] < row['Lower_limit'] or row['Store1'] > row['Upper_limit']:
        return 0
    else:
        return row['Store1']
    if row['Store2'] < row['Lower_limit'] or row['Store2'] > row['Upper_limit']:
        return 0
    else:
        return row['Store2']
    if row['Store3'] < row['Lower_limit'] or row['Store3'] > row['Upper_limit']:
        return 0
    else:
        return row['Store3']

Voici le résultat qui est faux. .

    ID  Store1  Store2  Store3  Min   Max  Lower_Limit Upper_limit
  123     100    1200     800  800  1200          900        1400
  246      15      16      45   15    45           11        55
  234      90     105     180   90   180          100          220
  236     100      90    9000   90  9000           70          140

import pandas as pd
data = [[123,100,1200,800,800,1200,900,1400],[246,15,16,45,15,45,11,55],[234,90,105,180,90,180,100,220],[236,100,90,9000,90,9000,70,140]]
df = pd.DataFrame(data,columns=['ID','Store1','Store2','Store3','Min','Max','Lower_Limit','Upper_limit'])
print (df)

Est-il possible de modifier mon code d'origine pour y parvenir?

p >


2 commentaires

pouvez-vous expliquer pourquoi la 1ère rangée du magasin 1, le magasin 3 ne doit pas être remplacé par 0?


C'est par erreur mis dans ...


3 Réponses :


0
votes

La fonction ci-dessous devrait faire le travail:

def calculate_outliers(df):
    df['Store1'][(df['Store1']<df['Lower_Limit']) | (df['Store1'] > df['Upper_limit'])] = 0
    df['Store2'][(df['Store2']<df['Lower_Limit']) | (df['Store2'] > df['Upper_limit'])] = 0
    df['Store3'][(df['Store3']<df['Lower_Limit']) | (df['Store3'] > df['Upper_limit'])] = 0


4 commentaires

Obtention de l'erreur ci-dessous: KeyError: ('Lower_Limit', 's'est produite à l'index 123')


KeyError: ('Lower_Limit', 's'est produit à l'index 123') TypeError: l'objet 'str' ne peut pas être interprété comme un entier Mon type de données est entier uniquement int64


@New_Coder s'il dit une erreur de clé, vérifiez les noms une fois !! Est-ce Lower_Limit ou Lower_limit !?


J'ai vérifié le nom des colonnes c'est le même.



0
votes
df.loc[(df['Store1']<df['Lower_Limit']) | (df['Store1']>df['Upper_limit']),['Store1'] ] = 0
and repeat for the other stores.

1 commentaires

Salut Baris, Obtention de la même erreur: TypeError: l'objet «str» ne peut pas être interprété comme un entier. KeyError: ('Lower_Limit', 's'est produit à l'index 123') mon type de données est int uniquement RangeIndex: 13 entrées, 0 à 12 colonnes de données (total 9 colonnes): ID 13 non-null int64 store1 13 non-null int64 store2 13 non nul int64 store3 13 non nul int64 Min 13 non nul int64 Max 13 non nul int64 Lower_limit 13 non nul int64 Upper_limit 13 non nul int64



1
votes

Essayez ceci:

def calculate_Outliers(df):
    m1= df['Store1'].lt(df['Lower_limit'])|df['Store1'].gt(df['Upper_limit'])
    m2 = df['Store2'].lt(df['Lower_limit'])|df['Store2'].gt(df['Upper_limit'])
    m3= df['Store3'].lt(df['Lower_limit'])|df['Store3'].gt(df['Upper_limit'])
    df.loc[m1,'Store1']=0
    df.loc[m1,'Store2']=0
    df.loc[m1,'Store3']=0
    print(df)
calculate_Outliers(df)

    ID  Store1  Store2  Store3  Min   Max  Lower_limit  Upper_limit
0  123       0       0       0  800  1200          900         1400
1  246      15      16      45   15    45           11           55
2  234       0       0       0   90   180          100          220
3  236     100      90    9000   90  9000           70          140

MODIFIER vous pouvez utiliser iloc [] si les noms de colonnes n'ont pas de chaîne commune:

m=df.iloc[:,1:4].lt(df.Lower_Limit,axis=0)|df.iloc[:,1:4].gt(df.Upper_limit,axis=0)
df.update(df.where(~m,0).iloc[:,1:4])
print(df)

    ID  Store1  Store2  Store3  Min   Max  Lower_Limit  Upper_limit
0  123       0    1200       0  800  1200          900         1400
1  246      15      16      45   15    45           11           55
2  234       0     105     180   90   180          100          220
3  236     100      90       0   90  9000           70          140

Emballage dans une fonction:

m=df.filter(like='Store').lt(df.Lower_Limit,axis=0)|df.filter(like='Store').\
                                                     gt(df.Upper_limit,axis=0)

df.update(df.where(~m,0).filter(like='Store'))
print(df)

    ID  Store1  Store2  Store3  Min   Max  Lower_Limit  Upper_limit
0  123       0    1200       0  800  1200          900         1400
1  246      15      16      45   15    45           11           55
2  234       0     105     180   90   180          100          220
3  236     100      90       0   90  9000           70          140


5 commentaires

Salut @ anky_91, Ceci est un exemple d'ensemble de données. L'ensemble de données d'origine a 39 variables et le nom des variables n'est pas commun comme celui mentionné dans l'exemple d'ensemble de données. Ce sont des noms extrêmes qui correspondent à une chaîne minimale. Pouvez-vous m'aider à trouver un code plus générique. (PS: il y a 3 millions de lignes)


@New_Coder si les noms de colonnes n'ont pas de chaîne commune donc vous ne pouvez pas utiliser filter , vous pouvez utiliser df.iloc [] si vous connaissez les positions des colonnes à mettre à jour. Vérifié.


Salut @ anky_91, ça marche merci beaucoup !!! C'était vraiment utile !! Je suis nouveau sur OOPS et je l'ai donc essayé d'une manière où je peux rendre le code produit tel qu'il ira en production. Pouvez-vous me faire savoir et m'aider à écrire une fonction en utilisant IF / ELSE l'original que j'ai essayé?


@New_Coder vérifier EDIT


Merci @ anky_91 dans ma fonction il n'accédait pas aux colonnes et aux lignes simultanément?