Pandas New Dataframe отображает верхние и нижние значения N для каждой группы - PullRequest
0 голосов
/ 18 января 2019

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

Мой ДФ выглядит так:

Unit    Influencer    Value
A       foo           321
B       foo           200
C       foo           20
D       foo           12
E       foo           3
A       bar           999
B       bar           209
C       bar           89
D       bar           34
E       bar           15
F       bar           2

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

Unit    Influencer    Value
    A       foo           321
    B       foo           200
    D       foo           12
    E       foo           3
    A       bar           999
    B       bar           209
    E       bar           15
    F       bar           2

Я пробовал что-то похожее на найденное решение здесь , но я получаю сообщение об ошибке «Индекс содержит повторяющиеся записи, не может изменить форму», которое, как я полагаю, связано с тем, что «Influencer» является индексом моей df , Если у меня df multiindex, создается новый df, но он неверный.

def get_top3(counts, col1, col2):

    top3 = (counts.groupby(col1))[col2].apply(lambda x: x.nlargest(3)).reset_index(level=1, drop=True).to_frame('VAL')

    top3 = counts.set_index(np.arange(len(counts)) % 3, append=True)['value'].unstack().add_prefix('VAL')

    return top3

Однако это создает Dataframe, который выглядит следующим образом:

VAL1  VAL2  VAL3
321   NaN   NaN
NaN   200   NaN
NaN   NaN   20
12    NaN   NaN
NaN   3     NaN
...

Любые предложения будут с благодарностью! Я также открыт для обратной связи о том, как мой выходной df может быть отформатирован. Спасибо!

Ответы [ 3 ]

0 голосов
/ 18 января 2019

Вы можете попробовать:

nlargest = df.groupby('Influencer')['Value'].nlargest(2).reset_index()['level_1'].values
nsmallest = df.groupby('Influencer')['Value'].nsmallest(2).reset_index()['level_1'].values

result = pd.concat([df.iloc[nlargest], df.iloc[nsmallest]]).sort_index()
print(result)

Вывод

   Unit Influencer  Value
0     A        foo    321
1     B        foo    200
3     D        foo     12
4     E        foo      3
5     A        bar    999
6     B        bar    209
9     E        bar     15
10    F        bar      2
0 голосов
/ 18 января 2019

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

#df=df.sort_values('Value')
g=df.groupby('Influencer')
pd.concat([g.head(2),g.tail(2)]).sort_index()
Out[693]: 
   Unit Influencer  Value
0     A        foo    321
1     B        foo    200
3     D        foo     12
4     E        foo      3
5     A        bar    999
6     B        bar    209
9     E        bar     15
10    F        bar      2
0 голосов
/ 18 января 2019

попробуйте создать такую ​​функцию, как:

def selc_df(df, x=2):
    return df.head(x).append(df.tail(x))

selc_df(df,2)

Пример:

>>> df
   A    B
0  1  345
1  2  366
2  3  299
3  3  455
4  4  879
5  5  321
6  5  957
7  6  543

Результат:

>>> def selc_df(df, x=2):
...     return df.head(x).append(df.tail(x))
...

>>> selc_df(df,2)
   A    B
0  1  345
1  2  366
6  5  957
7  6  543
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...