Вычислить значение в столбце на основе двух других столбцов Dataframe

#python #dataframe

#python #dataframe

Вопрос:

Я пытаюсь вычислить среднее значение для двух классов Physics и Math и включить его в отдельный столбец Mean. Кроме того, я просто пытаюсь вычислить среднее значение для классов, для которых обоим нужна оценка. Это работает для создания фильтра. Единственная мысль, которая не работает, — это вычислить среднее значение. Для отсутствующих он работает, но каким-то образом он устанавливает те, где у меня значение равно нулю, что странно. Данные выглядят следующим образом:

 Date        School  Math    Physics Mean    Flag
01.01.2020  ABC     3       4               1
01.03.2020  ABC     2       3               1
01.05.2020  ABC     2       1       1.5     2
01.07.2020  ABC     2       1               1
01.08.2020  ABC     2       1       1.5     2
01.04.2020  ABC     2                       3
01.06.2020  ABC             1               3
  

Мой код выглядит следующим образом:

 import pandas as pd

path = 'School_grades.xlsx'

df = pd.read_excel(path)
df_copy = df.copy(deep=True)

df_copy['Date'] = pd.to_datetime(df_copy.Date)

df_copy = df_copy[(df_copy["Flag"] != 3)]

df_copy['Mean'] = ((df_copy['Math']   df_copy['Physics'])/2).where(df_copy['Flag'] == 1)

print(df_copy)
  

Мой код предоставляет следующее, где столбцы, в которых я уже имел значение, включены в NaN:

        Date     School  Math  Physics  Mean  Flag
0 2020-01-01    ABC     3.0   4.0      3.5     1
1 2020-01-03    ABC     2.0   3.0      2.5     1
2 2020-01-05    ABC     2.0   1.0      NaN     2
3 2020-01-07    ABC     2.0   1.0      1.5     1
4 2020-01-08    ABC     2.0   1.0      NaN     2
  

Но я бы предпочел ожидать чего-то подобного:

        Date     School  Math  Physics  Mean  Flag
0 2020-01-01    ABC     3.0   4.0      3.5     1
1 2020-01-03    ABC     2.0   3.0      2.5     1
2 2020-01-05    ABC     2.0   1.0      1.5     2
3 2020-01-07    ABC     2.0   1.0      1.5     1
4 2020-01-08    ABC     2.0   1.0      1.5     2
  

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

1. Вероятно, что-то связанное с .where(df_copy['Flag'] == 1) тем, что NaN элементы имеют 2 в Flag столбце.

2. @Ouroborus, спасибо за ответ. Мне нужно только вычислить среднее значение, в котором отсутствует среднее значение. Флаг 1 показывает, что среднее значение отсутствует. Итак, как я могу вычислить только там, где Flag == 1, где равно 2, среднее значение существует, поэтому пересчитывать не нужно. Это немного понятнее

Ответ №1:

Ваш метод .where() не имеет оператора «else», но возвращает ряд для каждой строки фрейма данных. Это означает, что он возвращает только значения, в которых ваш оператор where имеет значение True, и пропущенные значения, в которых оно равно False, по сути отбрасывая ваши предыдущие результаты. Существует несколько способов решения этой проблемы. Один из них заключается в следующем, используя библиотеку numpy.

np.where() по сути, имеет ряд значений True / False. Где True использует следующую предоставленную серию, где false использует последнюю предоставленную серию. Здесь мы вставляем предыдущие средние значения.

 import numpy as np
df_copy['Mean'] = np.where(df_copy['Flag'] == 1, ((df_copy['Math']   df_copy['Physics'])/2), df_copy['Mean'])
  

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

1. Большое спасибо. Я горжусь, что у numpy есть нечто подобное :).

Ответ №2:

вы забыли добавить other параметр в pandas.where()

 >> df_copy['Mean'] = ((df_copy['Math']   df_copy['Physics'])/2).where(df_copy['Flag'] == 1,df_copy['Mean'])
>> print(df_copy)

  Date        School  Math  Physics  Mean  Flag
0  01.01.2020    ABC   3.0      4.0   3.5     1
1  01.03.2020    ABC   2.0      3.0   2.5     1
2  01.05.2020    ABC   2.0      1.0   1.5     2
3  01.07.2020    ABC   2.0      1.0   1.5     1
4  01.08.2020    ABC   2.0      1.0   1.5     2
5  01.04.2020    ABC   2.0      NaN   NaN     3
6  01.06.2020    ABC   NaN      1.0   NaN     3
  

Используется pandas.DataFrame.mean для вычисления среднего

 df_copy['Mean'] = df_copy[['Math','Physics']].mean(axis=1).where(df_copy.Flag == 1,df_copy['Mean'])
  

Вы также можете использовать numpy.где

 import numpy as np
df_copy['Mean'] = np.where(df_copy.Flag == 1,df_copy[['Math','Physics']].mean(axis=1),df_copy['Mean'])