Как рассчитать среднее значение для последних трех значений non-nan с использованием Python - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть датафрейм df выглядит следующим образом.Я хочу рассчитать среднее значение за последние 3 не нан столбца.Если есть менее трех не пропущенных столбцов, то среднее число отсутствует.

name day1 day2 day3 day4  day5 day6 day7
A    1     1   nan   2    3    0   3
B    nan   nan nan   nan  nan  nan 3
C    1     1   0     1    1    1   1
D    1     1   0     1    nan  1   4

Ожидаемый результат должен выглядеть следующим образом:

name day1 day2 day3 day4  day5 day6 day7    expected 
A    1     1   nan   2    3    0   3        2     <-  1/3*(day5 + day6 + day7)
B    nan   nan nan   nan  nan  nan 3        nan   <-  less than 3 non-missing
C    1     1   0     1    1    1   1        1     <-  1/3*(day5 + day6 + day7)
D    1     1   0     1    nan  1   4        2    <-  1/3 *(day4 + day6 + day7)

Я знаю, как рассчитать среднееиз последних трех столбцов и подсчитайте, сколько существует не пропущенных наблюдений.df.iloc[:, 5:7].count(axis=1) average of the last three column df.iloc[:, 5:7].count(axis=1) number of non-nan in the last three column

Если существует менее 3 не пропущенных наблюдений, я знаю, как установить среднее значение, чтобы пропустить, используя df.iloc[:, 1:7].count(axis=1) <= 3.

Но я изо всех сил пытаюсь найти способ вычислить среднее значение для трех последних не пропущенных столбцов.Кто-нибудь может научить меня, как решить эту проблему, пожалуйста?

Ответы [ 3 ]

0 голосов
/ 26 декабря 2018

Вы можете начать с вычисления столбца expected, применив следующую функцию:

expected = df.apply(lambda x: x[~x.isnull()][-3:].mean(), axis = 1)

И вставить эти значения в столбцы, которые имеют не менее 3 допустимых значений:

m = df.isnull().sum(axis=1) > 3
df.loc[~m,'expected'] = expected.mask(m)

       day1  day2  day3  day4  day5  day6  day7  expected
name                                                    
A      1.0   1.0   NaN   2.0   3.0   0.0     3       2.0
B      NaN   NaN   NaN   NaN   NaN   NaN     3       NaN
C      1.0   1.0   0.0   1.0   1.0   1.0     1       1.0
D      1.0   1.0   0.0   1.0   NaN   1.0     4       2.0
0 голосов
/ 26 декабря 2018

Векторизация с использованием justify -

N = 3 # last N entries for averaging
avg = np.mean(justify(df.values,invalid_val=np.nan,axis=1, side='right')[:,-N:],1)
df['expected'] = avg
0 голосов
/ 26 декабря 2018

Вы можете использовать pd.DataFrame.apply с пользовательской функцией.Это только частично векторизовано.

def mean_calculator(row):
    non_nulls = row.notnull()
    if non_nulls.sum() < 3:
        return np.nan
    return row[non_nulls].values[-3:].mean()

df['expected'] = df.iloc[:, 1:].apply(mean_calculator, axis=1)

print(df)

  name  day1  day2  day3  day4  day5  day6  day7  expected
0    A   1.0   1.0   NaN   2.0   3.0   0.0     3       2.0
1    B   NaN   NaN   NaN   NaN   NaN   NaN     3       NaN
2    C   1.0   1.0   0.0   1.0   1.0   1.0     1       1.0
3    D   1.0   1.0   0.0   1.0   NaN   1.0     4       2.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...