Vous ne savez pas comment calculer les conditions IF sur une trame de données comme vous le feriez dans un code python standard.

J'ai le df suivant:

Data Frame

Les valeurs de 'Label' correspondent à la valeur maximale de chaque ligne. Par exemple, ligne (0) la valeur maximale correspond à NO_2.

Je souhaite remplacer la valeur de 'Label' en fonction du tableau suivant:

ICA

Ainsi, par exemple, pour la ligne (0), la valeur 'Label' correspond à NO_2 comme mentionné précédemment, donc en vérifiant le graphique, la valeur de 67.120003 tombe dans la plage de 40-100 pour NO_2, donc je voudrais remplacer le 'Label' valeur pour la ligne (0) avec 2.

Voici un morceau de données od (* Remarque: je le modifie un peu afin d'obtenir la variabilité des valeurs maximales pour chaque contaminant à titre d'exemple):

            date        O_3     PM25        PM10        CO      SO_2         NO_2       Label
0   2001-01-01 01:00:00 7.86    12.505127   32.349998   0.45    26.459999   67.120003   67.120003
1   2001-01-01 02:00:00 7.21    12.505127   40.709999   0.48    20.879999   70.620003   70.620003
2   2001-01-01 03:00:00 7.11    12.505127   50.209999   0.41    21.580000   72.629997   72.629997
3   2001-01-01 04:00:00 7.14    12.505127   54.880001   0.51    19.270000   75.029999   75.029999
4   2001-01-01 05:00:00 8.46    12.505127   42.340000   0.19    13.640000   66.589996   66.589996
5   2018-04-30 20:00:00 63.00   200.000000  2.000000    0.30    4.000000    58.000000   200.000000
6   2018-04-30 21:00:00 49.00   400.000000  5.000000    0.30    4.000000    65.000000   400.000000
7   2018-04-30 22:00:00 49.00   3.000000    125.000000  0.30    4.000000    58.000000   125.000000
8   2018-04-30 23:00:00 48.00   7.000000    7.000000    0.30    4.000000    52.000000   52.000000
9   2018-05-01 00:00:00 52.00   4.000000    6.000000    0.30    4.000000    43.000000   52.000000

Donc, pour obtenir la valeur maximale de chaque ligne, ce que je fais est:

# Getting max values from each contaminant on each row
max_value = final_df.max(axis=1)

Et pour obtenir le nom de la colonne de valeur maximale:

# Obtaining maximum value column name for each row
label_max_colName = final_df.eq(final_df.max(1), 
axis=0).dot(final_df.columns)

J'ai suivi l'une des solutions proposées par @ TH14 qui est:

for index, val in final_df[[x for x in final_df.columns if x != 'date']].iterrows():
    max_column = np.argmax(val)
    max_column_val = np.max(val)

    if max_column == "O_3":
        if max_column_val <= 80:
            final_df.at[index, 'Label'] = 1

        if 80 < max_column_val < 120:
            final_df.at[index, 'Label'] = 2

        if 120 < max_column_val < 180:
            final_df.at[index, 'Label'] = 3

        if 180 < max_column_val < 240:
            final_df.at[index, 'Label'] = 4

        if 240 < max_column_val < 600:
            final_df.at[index, 'Label'] = 5

    if max_column == "NO_2":
        if max_column_val <= 40:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 100:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 200:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 400:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 1000:
            final_df.at[index, 'Label'] = 5

    if max_column == "SO_2":
        if max_column_val <= 100:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 200:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 350:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 500:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 1250:
            final_df.at[index, 'Label'] = 5

    if max_column == "PM10":
        if max_column_val <= 20:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 35:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 50:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 100:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 1200:
            final_df.at[index, 'Label'] = 5

    if max_column == "PM25":
        if max_column_val <= 10:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 20:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 25:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 50:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 800:
            final_df.at[index, 'Label'] = 5

Mais cela ne semble rien changer dans la colonne 'Label':

Result of computed Label column df

0
krm76 24 avril 2020 à 23:15

3 réponses

Meilleure réponse

J'ai seulement ajouté les conditions if else pour deux colonnes, mais vous avez compris.

df['Label'] = df.max(axis=1)


for index, val in final_df[[x for x in final_df.columns if x != 'date']].iterrows():
    max_column = np.argmax(val)
    max_column_val = np.max(val)

    if max_column == "O_3":
        if max_column_val <= 80:
            final_df.at[index, 'Label'] = 1

        if 80 < max_column_val < 120:
            final_df.at[index, 'Label'] = 2

        if 120 < max_column_val < 180:
            final_df.at[index, 'Label'] = 3

        if 180 < max_column_val < 240:
            final_df.at[index, 'Label'] = 4

        if 240 < max_column_val < 600:
            final_df.at[index, 'Label'] = 5

    if max_column == "NO_2":
        if max_column_val <= 40:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 100:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 200:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 400:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 1000:
            final_df.at[index, 'Label'] = 5

    if max_column == "SO_2":
        if max_column_val <= 100:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 200:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 350:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 500:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 1250:
            final_df.at[index, 'Label'] = 5

    if max_column == "PM10":
        if max_column_val <= 20:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 35:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 50:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 100:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 1200:
            final_df.at[index, 'Label'] = 5

    if max_column == "PM25":
        if max_column_val <= 10:
            final_df.at[index, 'Label'] = 1

        if 40 < max_column_val < 20:
            final_df.at[index, 'Label'] = 2

        if 100 < max_column_val < 25:
            final_df.at[index, 'Label'] = 3

        if 200 < max_column_val < 50:
            final_df.at[index, 'Label'] = 4

        if 400 < max_column_val < 800:
            final_df.at[index, 'Label'] = 5

Vous obteniez cette erreur avec la solution orKach parce que vous parcouriez la colonne de date.

Production:

       date                O_3         PM25        PM10      CO    SO_2        NO_2        Label
0   2001-01-01  01:00:00    7.86    12.505127   32.349998   0.45    26.459999   67.120003   2.0
1   2001-01-01  02:00:00    7.21    12.505127   40.709999   0.48    20.879999   70.620003   2.0
2   2001-01-01  03:00:00    7.11    12.505127   50.209999   0.41    21.580000   72.629997   2.0
3   2001-01-01  04:00:00    7.14    12.505127   54.880001   0.51    19.270000   75.029999   2.0
4   2001-01-01  05:00:00    8.46    12.505127   42.340000   0.19    13.640000   66.589996   2.0
5   2018-04-30  20:00:00    63.00   200.000000  2.000000    0.30    4.000000    58.000000   200.0
6   2018-04-30  21:00:00    49.00   400.000000  5.000000    0.30    4.000000    65.000000   400.0
7   2018-04-30  22:00:00    49.00   3.000000    125.000000  0.30    4.000000    58.000000   125.0
8   2018-04-30  23:00:00    48.00   7.000000    7.000000    0.30    4.000000    52.000000   2.0
9   2018-05-01  00:00:00    52.00   4.000000    6.000000    0.30    4.000000    43.000000   1.0
1
TH14 25 avril 2020 à 13:12

Une façon serait de définir une fonction qui reçoit le polluant et le niveau de concentration et renvoie le numéro d'étiquette comme suit:

def get_pollution_label(pollutant, concentration):
    if pollutant == 'o_3':
        if 0 < con < 80:
            return 1
    .
    .
    .

Après avoir écrit cette fonction, qui ne doit être qu'une série de 'if-else correspondant au tableau, vous pouvez parcourir les lignes et faire:

import numpy as np
import pandas as pd

for _, row in df.iterrows():
    df['Label'] = get_pollution_label(df.columns[np.argmax(row)], np.max(row))
1
orKach 24 avril 2020 à 20:48

En supposant que vous ayez vos deux tables en tant que trames de données

data_df = 
     O_3   PM25  ...  ...
0   7.86    ...
1    ...         ... 
2    ...              ...

Et

category_df = 
        1    2    3
O_3    80  120  ...
NO2    40  ...  
...   ...       ...

Vous pouvez également identifier les valeurs maximales et la colonne correspondante via df.max(axis=1) et df.idxmax(axis=1) respectivement. Aussi, import numpy as np pour utiliser la fonction np.where(condition) à des fins de comparaison et identifier l'étiquette maximale avec np.max().

max_df = pd.DataFrame(my_df.max(axis=1).values, index=my_df.idxmax(axis=1))
labels = []
for idx, row in max_df.iterrows():
    labels.append(np.max(np.where(row.values[0] < category_df.loc[idx])))
data_df["Label"] = pd.Series(labels)
0
MalteHerrmann 24 avril 2020 à 21:21