Получите положительные и отрицательные значения счетчиков, используя несколько столбцов сгруппированных групп Pandas - PullRequest
0 голосов
/ 30 января 2020

У меня есть pandas DataFrame, который выглядит следующим образом:

Person    Year    Weight Lost/Gained
Joe       2015          -5.7
Bryan     2015           7.8
Kelly     2015          -16.2
Frank     2016           10.3
Bill      2016          -22.1

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

Person    Year    Weight Lost/Gained    Pos Count    Neg Count      Pos Avg.     Neg Avg.
Joe       2015          -5.7                1           2             7.8         -10.95
Bryan     2015           7.8                1           2             7.8         -10.95
Kelly     2015          -16.2               1           2             7.8         -10.95
Frank     2016           10.3               1           1            10.3         -22.1
Bill      2016          -22.1               1           1            10.3         -22.1

Ближайший ответ, который я смог найти и попытаться реализовать, можно найти здесь: Как суммировать отрицательные и положительные значения отдельно при использовании groupby в pandas?

Однако я действительно не хотел бы переставлять весь фрейм данных, так как мой реальный фрейм данных намного больше.

Ответы [ 2 ]

3 голосов
/ 30 января 2020

Вот способ сделать:

# custom function
def func(f):
    pos = f['WeightLost'].gt(0)
    neg = f['WeightLost'].lt(0)
    pos_avg = f.loc[pos,'WeightLost'].mean()
    neg_avg = f.loc[neg,'WeightLost'].mean()
    return pd.Series([pos.sum(), neg.sum(), pos_avg, neg_avg], index=['Pos Count', 'Neg Count','Pos Avg','Neg Avg'])

f = df.groupby('Year').apply(func).reset_index()

print(f)

  Year  Pos Count  Neg Count  Pos Avg  Neg Avg
0  2015        1.0        2.0      7.8   -10.95
1  2016        1.0        1.0     10.3   -22.10
1 голос
/ 30 января 2020

Так как вам нужен ваш оригинальный df, мы можем воспользоваться картой.

def map_year_stats(df):

    col = 'Weight_Lost/Gained'


    rule_pos = df[col] > 0

    rule_neg = df[col] < 0

    pos_count = df[rule_pos].groupby('Year')[col].count()
    neg_count = df[rule_neg].groupby('Year')[col].count()

    pos_avg = df[rule_pos].groupby('Year')[col].mean()
    neg_avg = df[rule_neg].groupby('Year')[col].mean()

    df['pos_count'] = df['Year'].map(pos_count)
    df['neg_count'] = df['Year'].map(neg_count)
    df['pos_avg'] = df['Year'].map(pos_avg)
    df['neg_avg'] = df['Year'].map(neg_avg)
    return df

df_new = map_year_stats(df)

  Person  Year  Weight_Lost/Gained  pos_count  neg_count  pos_avg  neg_avg
0    Joe  2015                -5.7          1          2      7.8   -10.95
1  Bryan  2015                 7.8          1          2      7.8   -10.95
2  Kelly  2015               -16.2          1          2      7.8   -10.95
3  Frank  2016                10.3          1          1     10.3   -22.10
4   Bill  2016               -22.1          1          1     10.3   -22.10
...