2017-02-03 6 views
0

Учитывая проблемы с groupby() и nlargest(), как описано here и here. Я пытаюсь решить проблемы.отрезок оригинала df после groupby(). Наибольшая (x) операция

Примечание: для простоты я использовал nlargest(1), однако это может быть любое количество выборов.

{'city1': {0: 'Chicago', 
    1: 'Chicago', 
    2: 'Chicago', 
    3: 'Chicago', 
    4: 'Miami', 
    5: 'Houston', 
    6: 'Austin'}, 
'city2': {0: 'Toronto', 
    1: 'Detroit', 
    2: 'St.Louis', 
    3: 'Miami', 
    4: 'Dallas', 
    5: 'Dallas', 
    6: 'Dallas'}, 
'p234_r_c': {0: 5.0, 1: 4.0, 2: 2.0, 3: 0.5, 4: 1.0, 5: 4.0, 6: 3.0}, 
'plant1_type': {0: 'COMBCYCL', 
    1: 'COMBCYCL', 
    2: 'NUKE', 
    3: 'COAL', 
    4: 'NUKE', 
    5: 'COMBCYCL', 
    6: 'COAL'}, 
'plant2_type': {0: 'COAL', 
    1: 'COAL', 
    2: 'COMBCYCL', 
    3: 'COMBCYCL', 
    4: 'COAL', 
    5: 'NUKE', 
    6: 'NUKE',}} 

А) GroupBy city1 и возвращать строки, выбранные из оригинального DF

cols2 = ['city1','plant1_type','plant2_type'] 
df.loc[df2.groupby(cols2)['p234_r_c'].nlargest(1).reset_index().level_3] 

    city1 city2 p234_r_c plant1_type plant2_type 
6 Austin Dallas  3.0 COAL  NUKE 
3 Chicago Miami  0.5 COAL  COMBCYCL 
0 Chicago Toronto  5.0 COMBCYCL COAL 
2 Chicago St.Louis  2.0 NUKE  COMBCYCL 
5 Houston Dallas  4.0 COMBCYCL NUKE 
4 Miami Dallas  1.0 NUKE  COAL 

выше выглядит хорошо

B) GroupBy city2 и возвращают строки, выбранные из оригинального ФР

Поскольку тот же код, который используется в #A, генерирует фиктивный результат при попытке для groupby city2, было предложено обходное решение следующий:

cols = ['city2','plant1_type','plant2_type'] 
df.set_index(cols).groupby(level=cols)['p234_r_c'].nlargest(1) 


city2  plant1_type plant2_type 
Toronto COMBCYCL  COAL   5.0 
Detroit COMBCYCL  COAL   4.0 
St.Louis NUKE   COMBCYCL  2.0 
Miami  COAL   COMBCYCL  0.5 
Dallas NUKE   COAL   1.0 
      COMBCYCL  NUKE   4.0 
      COAL   NUKE   3.0 

Теперь, как я могу использовать этот результат для возврата строки, выбранной из оригинала ДФА, как я сделал в #A?

Примечание: имел оригинальный DF имел дополнительный ряд, который сделал результат из groupby.nlargest() для city2 есть группы, где по меньшей мере одна группа имела размер больший, чем 1, то код в #A может быть использован для #B.

ответ

2

Если у меня что-то не хватает (и я согласен, что здесь есть коды, скрывающиеся в коде pandas), мы можем обойти любые трудности относительно просто.

Способ № 1: использование loc и idxmax:

In [21]: df.loc[df.groupby(cols2)["p234_r_c"].idxmax()] 
Out[21]: 
    city1  city2 p234_r_c plant1_type plant2_type 
6 Austin Dallas  3.0  COAL  NUKE 
3 Chicago  Miami  0.5  COAL COMBCYCL 
0 Chicago Toronto  5.0 COMBCYCL  COAL 
2 Chicago St.Louis  2.0  NUKE COMBCYCL 
5 Houston Dallas  4.0 COMBCYCL  NUKE 
4 Miami Dallas  1.0  NUKE  COAL 

In [22]: df.loc[df.groupby(cols)["p234_r_c"].idxmax()] 
Out[22]: 
    city1  city2 p234_r_c plant1_type plant2_type 
6 Austin Dallas  3.0  COAL  NUKE 
5 Houston Dallas  4.0 COMBCYCL  NUKE 
4 Miami Dallas  1.0  NUKE  COAL 
1 Chicago Detroit  4.0 COMBCYCL  COAL 
3 Chicago  Miami  0.5  COAL COMBCYCL 
2 Chicago St.Louis  2.0  NUKE COMBCYCL 
0 Chicago Toronto  5.0 COMBCYCL  COAL 

Способ № 2: сортировка по p234_r_c и использовать last:

In [17]: df.sort_values("p234_r_c").groupby(cols2, as_index=False).last() 
Out[17]: 
    city1 plant1_type plant2_type  city2 p234_r_c 
0 Austin  COAL  NUKE Dallas  3.0 
1 Chicago  COAL COMBCYCL  Miami  0.5 
2 Chicago COMBCYCL  COAL Toronto  5.0 
3 Chicago  NUKE COMBCYCL St.Louis  2.0 
4 Houston COMBCYCL  NUKE Dallas  4.0 
5 Miami  NUKE  COAL Dallas  1.0 

In [18]: df.sort_values("p234_r_c").groupby(cols, as_index=False).last() 
Out[18]: 
     city2 plant1_type plant2_type city1 p234_r_c 
0 Dallas  COAL  NUKE Austin  3.0 
1 Dallas COMBCYCL  NUKE Houston  4.0 
2 Dallas  NUKE  COAL Miami  1.0 
3 Detroit COMBCYCL  COAL Chicago  4.0 
4  Miami  COAL COMBCYCL Chicago  0.5 
5 St.Louis  NUKE COMBCYCL Chicago  2.0 
6 Toronto COMBCYCL  COAL Chicago  5.0 

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

In [27]: df.sort_values("p234_r_c").groupby(cols, as_index=False).tail(2) 
Out[27]: 
    city1  city2 p234_r_c plant1_type plant2_type 
3 Chicago  Miami  0.5  COAL COMBCYCL 
4 Miami Dallas  1.0  NUKE  COAL 
2 Chicago St.Louis  2.0  NUKE COMBCYCL 
6 Austin Dallas  3.0  COAL  NUKE 
1 Chicago Detroit  4.0 COMBCYCL  COAL 
5 Houston Dallas  4.0 COMBCYCL  NUKE 
0 Chicago Toronto  5.0 COMBCYCL  COAL 
+0

Say, если я использую 'Метод # 1' и сделать' groupby' используя только 'Cols = [ 'city1']' и хотите 'большой 2 (или N) от p234_r_c'. Я попробовал следующее с «N = 2», и результат будет таким же, как и для «N = 1». 'df.loc [df.groupby (cols2) [" p234_r_c "]. Idxmax (2)]' – codingknob

+0

для 'N = 2', у нас должно быть 2 строки для Чикаго. т.е. отсутствует следующая строка: 'Чикаго \t Detroit \t 4.0 \t COMBCYCL \t COAL' – codingknob

+0

@codingknob:' idxmax' не имеет параметра 'n', поэтому, если есть документация, где-то предполагающая, что это так, напишите ошибку, потому что нам нужно это починить. :-( – DSM