Сохранить наибольшее абсолютное значение и вернуть среднее значение из строк с повторяющимся индексом - PullRequest
0 голосов
/ 09 декабря 2018

У меня есть набор значений с повторяющимся индексом в кадре данных:

         value
CDE   2.318620
CDE  -3.097715
LXU  -3.791043
LXU   4.818995
SWN   3.059964
SWN  -4.349304
OAS  -3.336539
LPI  -3.037097
LPI  -5.701044
LPI  -3.519923
CZR  -3.270018
CZR  -3.056712

Требуемый результат - сохранить только самые высокие абсолютные значения и вернуть средние значения в новом столбце:

         value    average
CDE  -3.097715  -0.389547
LXU   4.818995   0.513976
SWN  -4.349304  -0.644670
OAS  -3.336539  -3.336539
LPI  -5.701044  -4.086021
CZR  -3.270018  -3.163365

Я пытался .apply (лямбда) к дублирующимся строкам, но получил ошибку "оси":

max_absolute = lambda x: max(x.min(), x.max(), key=abs)
df_duplicate_absmax = df.groupby(df.index).apply(max_absolute, axis=1)

ps: Адаптация решения Абхи для работы с NaN:

df1 = df.groupby(df.index)['value'].agg([lambda x: max(x[~np.isnan(x)], key=abs), 'mean'])

Ответы [ 3 ]

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

Вот решение, использующее groupby + agg с двумя функциями, одна для вычисления максимума по абсолютному значению, другая для вычисления среднего:

def max_abs(x):
    return x.iloc[x.abs().values.argmax()]

res = df.groupby(level=0).agg([max_abs, 'mean'])\
        .xs('value', axis=1, drop_level=True)

print(res)

      max_abs      mean
CDE -3.097715 -0.389547
CZR -3.270018 -3.163365
LPI -5.701044 -4.086021
LXU  4.818995  0.513976
OAS -3.336539 -3.336539
SWN -4.349304 -0.644670
0 голосов
/ 09 декабря 2018
from io import StringIO
import pandas as pd
df = pd.read_fwf(StringIO("""
cod      value
CDE   2.318620
CDE  -3.097715
LXU  -3.791043
LXU   4.818995
SWN   3.059964
SWN  -4.349304
OAS  -3.336539
LPI  -3.037097
LPI  -5.701044
LPI  -3.519923
CZR  -3.270018
CZR  -3.056712
"""), header=1, Index=None)

# Create a new column with absoulte value
df['abs_value'] = df['value'].abs()

# Calulate the mean in new data farame, grouped by code using
# pandas groupped aggregation naming the column average
df_avg = df.groupby("cod").value.agg([('average', 'mean')])

# Choose the row within group with largest abs value
df_abs = df.sort_values("abs_value").groupby("cod").tail(1)[["cod", "value"]]

# Join the average and the max
df_abs.join(df_avg, on="cod")

Результат:

    cod     value   average
1   CDE -3.097715 -0.389547
10  CZR -3.270018 -3.163365
6   OAS -3.336539 -3.336539
5   SWN -4.349304 -0.644670
3   LXU  4.818995  0.513976
8   LPI -5.701044 -4.086021
0 голосов
/ 09 декабря 2018

Использование:

df1 = df.groupby(df.index)['value'].agg([lambda x: max(x,key=abs), 'mean'])

df1.columns = ['value', 'average']

print (df1)

        value   average
CDE -3.097715 -0.389547
CZR -3.270018 -3.163365
LPI -5.701044 -4.086021
LXU  4.818995  0.513976
OAS -3.336539 -3.336539
SWN -4.349304 -0.644670
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...