Новичок в пандах, так что я могу упустить что-то очевидное здесь. Мое намерение состоит в том, чтобы просто перечислить главные проекты усилиями, сгруппированными по типу. Вот CSV, с которым я работаю как вход:


project,effort,type
p1,6,feature
p2,4.5,feature
p3,4.375,bug
p4,4,bug
p5,3.875,bug
p6,3.5,upgrade
p7,3.5,feature
p8,3,upgrade
p9,2,upgrade

Теперь моя цель - показать три лучших проекта по группам по типу. Вот что я сделал:

dev=pd.read_csv('test.csv')
dev.sort_values(['effort'], ascending=False).groupby('type').head(3)

Вот что я вижу в ipython:

  project  effort     type
0      p1   6.000  feature
1      p2   4.500  feature
2      p3   4.375      bug
3      p4   4.000      bug
4      p5   3.875      bug
5      p6   3.500  upgrade
6      p7   3.500  feature
7      p8   3.000  upgrade
8      p9   2.000  upgrade

Хотя строки кажутся точными, я ожидал, что на выходе будут сгруппированы функции, ошибки и обновления, даже если это означало, что усилия не были строго отсортированы в порядке убывания, например так:

Ожидаемое :

  project  effort     type
0      p1   6.000  feature
1      p2   4.500  feature
6      p7   3.500  feature
2      p3   4.375      bug
3      p4   4.000      bug
4      p5   3.875      bug
5      p6   3.500  upgrade
7      p8   3.000  upgrade
8      p9   2.000  upgrade

То есть все функции, сопровождаемые ошибками, сопровождаемыми обновлениями (не нужны в том же порядке, но, по крайней мере, сгруппированы правильно).

Я что-то упускаю из виду? Заранее спасибо за ваши ответы!

0
ragebiswas 2 Май 2019 в 14:47

3 ответа

Лучший ответ

Обновление:

Сначала sort в соответствии с effort. groupby type, возьмите head, а затем sort снова type.

df.sort_values('effort', ascending=False).groupby(['type']).head(3).sort_values('type')
1
akilat90 2 Май 2019 в 15:00

head(3) по крайней мере имеет размер каждой группы и поэтому печатает весь DataFrame.

import pandas as pd
import csv
from pandas.compat import StringIO

print(pd.__version__)

csvdata = StringIO("""project,effort,type
p1,6,feature
p2,4.5,feature
p3,4.375,bug
p4,4,bug
p5,3.875,bug
p6,3.5,upgrade
p7,3.5,feature
p8,3,upgrade
p9,2,upgrade""")

df = pd.read_csv(csvdata, sep=",")

print(df)
print(df.sort_values(['effort'], ascending=False).groupby('type').head(1))

Производит

0.24.2
  project  effort     type
0      p1   6.000  feature
1      p2   4.500  feature
2      p3   4.375      bug
3      p4   4.000      bug
4      p5   3.875      bug
5      p6   3.500  upgrade
6      p7   3.500  feature
7      p8   3.000  upgrade
8      p9   2.000  upgrade
  project  effort     type
0      p1   6.000  feature
2      p3   4.375      bug
5      p6   3.500  upgrade

Но код MCVE показывает только использование Grouper. Функция, такая как mean(), будет более полезной.

0
Rich Andrews 2 Май 2019 в 11:57

В предоставленном примере набора данных каждый проект представляет собой отдельную запись определенного типа. В этом случае мы можем получить 3 лучших проекта усилиями nlargest, а затем groupby и sum усилиями:

df.nlargest(3, 'effort').groupby('type').sum()

Выход:

         effort
type           
bug       4.375
feature  10.500

Постскриптум Вот немного объяснить, что пошло не так

dev.sort_values(['effort'], ascending=False).groupby('type').head(3)

Когда вы используете head для объекта GroupBy, он берет первые элементы для каждой группы (см. Документ по head), так что вы получаете топ-3 за каждую из функций, ошибок и «обновить». Если вы примените head до groupby, это будет работать правильно:

dev.sort_values(['effort'], ascending=False).head(3).groupby('type').sum()

По сути, это то же самое, что и в моем решении выше, с той лишь разницей, что я использовал nlargest вместо сортировки и применения head впоследствии (nlargest немного более кратко)

Обновить: вы можете предварительно отсортировать по типу (по возрастанию) и по усилию (по убыванию) + groupby и head:

df.sort_values(['type', 'effort'], ascending=[1,0]).groupby('type').head(3)

Выход:

  project  effort     type
2      p3   4.375      bug
3      p4   4.000      bug
4      p5   3.875      bug
0      p1   6.000  feature
1      p2   4.500  feature
6      p7   3.500  feature
5      p6   3.500  upgrade
7      p8   3.000  upgrade
8      p9   2.000  upgrade

По всей видимости, в pandas обсуждается here открытый вопрос на этот счет.

1
perl 2 Май 2019 в 16:13