0
votes

Calcul moyen pondéré conditionnel en pandas

J'ai 2 dataframes comme ci-dessous

enseignant_commission_df comme ci-dessous xxx

étudiants_df comme ci-dessous. (NOTE Aucun étudiant pour maths dans Harare et Norton ) xxx

J'ai besoin de Calculez la commission moyenne pondérée de chaque ville, avec une condition.

Tout d'abord, je vais donner la sortie souhaitée et expliquer la méthodologie.

La sortie souhaitée est ci-dessous. xxx

méthodologie de calcul

Si dans une colonne de ville [Harare, redcliff, Norton] , si les étudiants de tout sujet [Science, Anglais, Maths, Musique] est zéro alors que ce particulier Sujet 's enseignant_commission doit être supprimé dans le poids.

Par exemple, dans étudiants_df : prenez la ville harare colonne de science sujet. Étant donné que maths est zéro dans harare , le enseignant_commission sera calculé comme suit. 15 * [0,10 / (0.415 - 0.09)] = 4.62 Notez le 0.09 Retrait dans le dénominateur du total. où comme dans radcliff il est calculé sans retrait comme 18 * [0.125 / 0.515] = 4.37

J'espère que mon explication est claire.

Ceci peut être facilement effectué dans Microsoft Excel à l'aide d'un si condition. Mais je cherche une solution de pandas évolutive.

Je ne sais pas comment démarrer le processus de calcul. Par conséquent, donnez-moi s'il vous plaît un coup de pied commence à résoudre ceci. xxx


2 commentaires

Pouvez-vous expliquer comment vous obtenez 41,5% et 51,5%?


Total de chaque colonne de enseignant_commission_df . C'est en fait pourcentage .Pour facilité d'explication que j'ai mentionné % dans la méthodologie de calcul . Je l'ai déjà résolu. renvoyer ma propre réponse ci-dessous


3 Réponses :


1
votes

Donc, ce dont vous avez besoin est l'index de la ligne / de la colonne de chaque valeur null vide dans le Dataframe?

Vous pouvez utiliser Numpy.Où (). En fonction du type de données de votre objet NULL, vous pourriez

  1. chargez df comme tableau NP
  2. i, j = np.where ("nan")
  3. i et j sont maintenant des index que vous pouvez utiliser pour éliminer les poids si les tailles sont identiques ou utilisent DataFrame.index pour trouver quel poids à enlever.

    Remplacez Nan avec NULL ou "" Selon votre DTYPE

    Ceci est similaire à ce que vous feriez dans Excel en utilisant un si

    Personnellement, je voudrais simplement faire une copie Dataframe binaire I.e Mettez un 1 partout où il existe une valeur non nulle dans le Dataframe et 0 à NULL Emplacement, puis il suffit de miltiplez les deux vecteurs. Mais c'est probablement plus de traitement aérien


1 commentaires

Merci et avancé. Basé sur votre suggestion, j'ai réussi à résoudre ce problème purement à partir de numpy . N'hésitez pas à donner des suggestions pour améliorer mon code. Merci.!



0
votes

basé sur la suggestion donnée par utilisateur: AAAK code>. J'ai réussi à résoudre ce problème purement à partir de numpy code>.

# Load data and fill N/A values
Teacher_Commission_df = pd.read_excel('data_Teacher.xlsx',index_col='Subject', skipfooter=1)
Students_df = pd.read_excel('data_Studenst.xlsx',index_col='Subject')
Students_df.fillna(value=0, inplace= True)


# Convert Dataframes to Numpy Arrays
T = Teacher_Commission_df.to_numpy(dtype='float')
S = Students_df.to_numpy(dtype='float')

# Filter index of ZERO values from Students Numpy Array and 
# replace the correponding Values in teachers Numpy Array
T[np.where(S == 0)] = 0

# creat a temporary Sum numpy array for calculation
Total_Teacher = T.sum(axis=0)

#calculate incentives
Calculations = T * (S/Total_Teacher)

incentives = (pd.DataFrame(Calculations, columns=Students_df.columns, index=Students_df.index)
                  .round(decimals=2)
                  .reset_index())
incentives


0 commentaires

1
votes

Solution à l'aide de Pandas

Il s'agit en réalité de deux lignes de code à l'aide de Pandas: xxx

résultat (avec la nouvelle 3 chiffres de précision données.) xxx

explication du code ci-dessus

note : cette explication utilise la précision précision à 2 chiffres donnée dans la question initiale.

  • Tout d'abord, vous pouvez utiliser une indexation booléenne, en utilisant le DataFrame.isnull () xxx
    • Ensuite, vous pouvez sélectionner les valeurs non nulles à partir du enseignant_commission_df en utilisant Indexation booléenne et non opérateur ( ~ ). xxx
      • Enregistrez ce fichier de données temporaire dans une nouvelle variable, DF_TMP : xxx
        • Maintenant, nous voulons diviser la valeur dans chaque cellule par la somme des valeurs de colonne. La somme des valeurs de colonne est calculée, ignorant les NANs, à l'aide de Apply () et np.nansum : xxx
          • Ensuite, combinez le sommation avec la division, en utilisant dataframe.div () : xxx
            • Ensuite, multipliez les données de données (multiplication d'élément d'élément): xxx


4 commentaires

Semble élégant. Mais, ne pas avoir la réponse requise. Voir le résultat requis mentionné dans ma question.


Ah! Droite, dans la dernière réponse, j'ai eu une erreur de copie-coller! :) Corrigée! Maintenant, la réponse est identique au résultat requis (à l'excl place des erreurs de rond-point, car les exemples de données sont données uniquement avec une précision de 2 chiffres).


Oui. votre code est correct. Mais, je me demande pourquoi l'arrondissement, lorsque j'ai donné les données à 3 chiffres de précision?


Les données d'origine ont été données en 2 chiffres de précision (à l'époque où j'ai copié les données pour créer l'exemple). J'ai maintenant mis à jour les valeurs finales avec les données de saisie de précision à 3 chiffres.