Как вычислить условные выражения (IF) в ячейке столбца в pandas? - PullRequest
0 голосов
/ 24 апреля 2020

Не уверен, как вычислять условные IF на кадре данных, как вы это делали бы в стандартном python коде.

У меня есть следующее df:

Data Frame

Значения в «Метке» соответствуют максимальному значению из каждой строки. Например, в строке (0) максимальное значение соответствует NO_2.

Я хочу заменить значение в «Метке» на основе следующей диаграммы:

ICA

Так, например, для строки (0) значение «Метка» соответствует NO_2, как упоминалось ранее, поэтому при проверке графика значение 67.120003 попадает в диапазон 40-100 для NO_2, поэтому я хотел бы заменить значение 'Label' для строки (0) на 2.

Вот часть данных (* Примечание: я изменяю это немного, чтобы получить изменчивость для максимальных значений для каждого загрязнитель ради примера):

            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

Итак, чтобы получить максимальное значение из каждой строки, я делаю следующее:

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

И чтобы получить имя столбца максимального значения:

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

Я следовал одному из предложенных решений от @ TH14, который:

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

, но, похоже, ничего не меняет в метке столбец:

Result of computed Label column df

Ответы [ 3 ]

1 голос
/ 25 апреля 2020

Я добавил условия if else только для двух столбцов, но вы поняли идею.

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

Вы получили эту ошибку с помощью решения orKach, поскольку вы перебирали столбец даты.

Вывод:

       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 голос
/ 24 апреля 2020

Одним из способов будет определение функции, которая получает загрязнитель и уровень концентрации и возвращает номер метки следующим образом:

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

После написания этой функции, которая должна быть просто последовательностью -наже соответствует таблице, вы можете перебирать строки и делать:

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))
0 голосов
/ 25 апреля 2020

Если у вас есть обе таблицы в виде фреймов данных

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

и

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

, вы также можете определить максимальные значения и соответствующий столбец через df.max(axis=1) и df.idxmax(axis=1) соответственно , Кроме того, import numpy as np для использования функции np.where(condition) в целях сравнения и определения максимальной метки с помощью 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)
...