Условный оператор / оператор If с кадрами данных

#python #pandas #dataframe #if-statement #conditional-statements

Вопрос:

Я пытаюсь присвоить значение столбцу «Процент» на основе нескольких столбцов «Класс» и «Значение»

Ниже приведена ссылка с моим фреймом данных: https://filebin.net/fo2wk7crmwf0fycc

Это та логика, которую я хочу применить:

 If df['Class'] equals 2 or 3, and if df['Value'] is less than 0.5, set df['Percentage'] to 0
If df['Class'] equals 2 or 3, and if df['Value'] is > 0.5 and <= 0.7, set df['Percentage'] to 0.25
If df['Class'] equals 2 or 3, and if df['Value'] is > 0.7 and <= 0.9, set df['Percentage'] to 0.5
Else set df['Percentage'] to 1
 

Ниже приведен пример вывода, который я ищу:

Класс Ценность Процент
2 0.01 0
2 0.6 0.25
3 0.9 0.5
3 3 1

Спасибо

Ответ №1:

Тупой и searchsorted

При использовании searchsorted вам не нужно включать границы, как 0 и 1 в этом случае.

 bins =  np.array([.5, .7, .9])
labels = np.array([0, .25, .5, 1])
cut = bins.searchsorted(df.Value)
results = labels[cut]

df.assign(Percentage=np.where(df['Class'].isin([2, 3]), results, 1))

       Class     Value  Percentage
0          2  0.000620         0.0
1          2  0.000620         0.0
2          3  0.001240         0.0
3          4  0.000620         1.0
4          5  0.000620         1.0
...      ...       ...         ...
14782      5  0.001178         1.0
14783      2  0.001116         0.0
14784      3  0.001178         0.0
14785      5  0.000310         1.0
14786      5  0.001116         1.0

[14787 rows x 3 columns]
 

Панды cut

При использовании pd.cut вам ДЕЙСТВИТЕЛЬНО нужны границы, потому что Панды будут создавать интервалы.

 #                        / boundaries 
#                       ↓              ↓
cut = pd.cut(df.Value, [0, .5, .7, .9, 1], labels=[0, .25, .5, 1])

df.assign(Percentage=np.where(df['Class'].isin([2, 3]), cut, 1))

       Class     Value  Percentage
0          2  0.000620         0.0
1          2  0.000620         0.0
2          3  0.001240         0.0
3          4  0.000620         1.0
4          5  0.000620         1.0
...      ...       ...         ...
14782      5  0.001178         1.0
14783      2  0.001116         0.0
14784      3  0.001178         0.0
14785      5  0.000310         1.0
14786      5  0.001116         1.0

[14787 rows x 3 columns]
 

Ответ №2:

Вы также можете использовать pure np.where , как показано ниже:

 import numpy as np    
df['Percentage'] = np.where((df['Class'].isin([2, 3]) amp; (df['Value'] <= 0.5)), 0, 
                            np.where((df['Class'].isin([2, 3]) amp; (df['Value'] > 0.5) amp; (df['Value'] <= 0.7)), 0.25,
                                np.where((df['Class'].isin([2, 3]) amp; (df['Value'] > 0.7) amp; (df['Value'] <= 0.9) ), 0.5, 1)))
 

np.where это похоже на условное утверждение «если-то-еще», которое вы легко можете понять.

        Class     Value  Percentage
0          2  0.000620         0.0
1          2  0.000620         0.0
2          3  0.001240         0.0
3          4  0.000620         1.0
4          5  0.000620         1.0
...      ...       ...         ...
14782      5  0.001178         1.0
14783      2  0.001116         0.0
14784      3  0.001178         0.0
14785      5  0.000310         1.0
14786      5  0.001116         1.0

[14787 rows x 3 columns]
 

Комментарии:

1. Большое вам спасибо, это решение отлично работает!