Вычислять только среднее значение строк данных в кадре данных без значений NaN - PullRequest
0 голосов
/ 06 мая 2020

У меня есть датафрейм с идентификаторами клиентов и их расходами за 2014-2018 гг. Я хочу иметь среднее значение расходов за 2014-2018 годы для каждого идентификатора в фрейме данных. Однако есть одно условие: если одна из ячеек в строках (2014-2018) пуста, должно быть возвращено NaN. Поэтому я хочу, чтобы среднее значение вычислялось только тогда, когда все 5 ячеек-строк в столбцах 2014-2018 имеют значение numeri c.

Исходный фрейм данных:

2014   2015  2016  2017   2018   ID
100  122.0   324   632    NaN  12.0
120  159.0    54   452  541.0  96.0
NaN  164.0   687   165  245.0  20.0
180  421.0   512   184  953.0  73.0
110  654.0   913   173  103.0  84.0
130    NaN   754   124  207.0  26.0
170  256.0   843    97  806.0  87.0
140  754.0    95   101  541.0  64.0
 80  985.0   184    84   90.0  11.0
 96   65.0   127   130  421.0  34.0

Желаемый результат

2014   2015  2016  2017   2018    ID    mean
 100  122.0   324   632    NaN  12.0     NaN
 120  159.0    54   452  541.0  96.0  265.20
 NaN  164.0   687   165  245.0  20.0     NaN
 180  421.0   512   184  953.0  73.0  450.00
 110  654.0   913   173  103.0  84.0  390.60
 130    NaN   754   124  207.0  26.0     NaN
 170  256.0   843    97  806.0  87.0  434.40
 140  754.0    95   101  541.0  64.0  326.20
  80  985.0   184    84   90.0  11.0  284.60
  96   65.0   127   130  421.0  34.0  167.80

Пробный код: -> это, однако, дает мне только среднее значение, игнорируя условие NaN. Это какая-то краткая лямбда-функция, которая может добавить условие в код?

import pandas as pd

import numpy as np



data = pd.DataFrame({"ID":   [12,96,20,73,84,26,87,64,11,34],
                     
                   "2014": [100,120,np.nan,180,110,130,170,140,80,96],
                     
                   "2015": [122,159,164,421,654,np.nan,256,754,985,65],

                   "2016": [324,54,687,512,913,754,843,95,184,127],
   
                   "2017": [632,452,165,184,173,124,97,101,84,130],
 
                   "2018": [np.nan,541,245,953,103,207,806,541,90,421]})



print(data)


fiveyear = ["2014", "2015", "2016", "2017", "2018"] -> if a cell in these rows is empty(NaN), then NaN should be in the new 'mean'-column. I only want the mean when, all 5 cells in the row have a numeric value.



data.loc[:, 'mean'] = data[fiveyear].mean(axis=1)


print(data)

Ответы [ 2 ]

3 голосов
/ 06 мая 2020

Используйте dropna, чтобы удалить строки перед вычислением среднего. Поскольку pandas будет выровнен по индексу при обратном присвоении результата, и эти строки были удалены, результат этих удаленных строк будет NaN

df['mean'] = df[fiveyear].dropna(how='any').mean(1)

Также возможно mask результат только для тех строки, которые все не равны NULL

df['mean'] = df[fiveyear].mean(1).mask(df[fiveyear].isnull().any(1))

Немного больше похоже на взлом, но поскольку вы знаете, что вам нужны все 5 значений, вы также можете использовать sum, который поддерживает аргумент min_count, поэтому все, что имеет менее 5 значений, будет NaN

df['mean'] = df[fiveyear].sum(1, min_count=len(fiveyear))/len(fiveyear)
2 голосов
/ 06 мая 2020

Это то же самое, что и ответ @ALollz, но с гибким способом обнаружения всех столбцов независимо от того, сколько лет в df

#get years columns in a list
yearsCols= [c for c in df if c != 'ID']

#calculate mean
df['mean'] = df[yearsCols].dropna(how='any').mean(1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...