Можно ли использовать групповую функцию Панд с непересекающимися группами? - PullRequest
1 голос
/ 07 октября 2019

Я пытаюсь расширить программу на Python. В настоящее время он использует groupby для выполнения некоторой работы по сегментации.

Расширение позволит рядам находиться в нескольких группах. Я не уверен, позволяет ли groupby это или как имитировать это. Или, если мне просто придется заново реализовать всю функциональность ...

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

Ниже представлены три ВОЗМОЖНЫХ представления данных. Любой будет хорошо, или другие. Мне просто нужно, чтобы они могли привести пример, и я не хочу ограничивать ответы одним конкретным форматом данных.

Version1 Существует один столбец 'grp', и он может иметь несколько значений (разделенных запятыми, но может быть любым):

In [9]: v1                                                                                              
Out[9]: 
  name  value   grp
0    a     34     x
1    b     98   x,y
2    c      8     y
3    d      3     z

Version2 каждое возможное значение группыимеет столбец 1/0:

In [14]: v2                                                                                             
Out[14]: 
  name  value  x  y  z
0    a     34  1  0  0
1    b     98  1  1  0
2    c      8  0  1  0
3    d      3  0  0  1

В версии 3 есть 3 столбца grp, каждый с одним или нулевым значением, что позволяет каждой строке быть в трех группах:

In [20]: v3                                                                                             
Out[20]: 
  name  value grp1 grp2 grp3
0    a     34    x          
1    b     98    x    y     
2    c      8    y          
3    d      3    z

Другие реализации также были бы хороши, но я хотел бы привести несколько возможных примеров.

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

v1.MULTIgroupby('grp').count()    

, чтобы дать:

grp   count
x     2
y     2
z     1 

Таким образом, даже если есть только 4 строки, количество добавляется до 5. Это правильно, ичто я хочу. count () это только один пример. Я хочу быть в состоянии сделать среднее, и медиана, и эфирные группы по агг функции.

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

ETA: Добавление более сложных примеров:

Добавление столбца дополнительного значения:

In [27]: v1                                                                                             
Out[27]: 
  name  value   grp  value2
0    a     34     x      45
1    b     98  x, y       9
2    c      8     y     345
3    d      3     z       2

In [28]: v2                                                                                             
Out[28]: 
  name  value  x  y  z  value2
0    a     34  1  0  0      45
1    b     98  1  1  0       9
2    c      8  0  1  0     345
3    d      3  0  0  1       2

In [29]: v3                                                                                             
Out[29]: 
  name  value grp1 grp2 grp3  value2
0    a     34    x                45
1    b     98    x    y            9
2    c      8    y               345
3    d      3    z                 2

с помощью groupby, Iможно сделать:

v3.groupby('grp1').mean()

Я получу среднее значение для значения и значения2 по x, y и z.

      value  value2
grp1               
x        66      27
y         8     345
z         3       2

Я хочу:

      value  value2
grp               
x        66      27
y         53     177
z         3       2

И да, я могу рассчитать это сам с циклом по всем столбцам, которые мне нужны, а затем с циклом по всем столбцам grpв версии 2, например, и фильтрация, а затем запуск функции mean (). Но прелесть группового в том, что мне НЕ НУЖНО ... Я надеюсь избежать этого ...

Тот факт, что мне так трудно выразить это, вероятно, означает, что это достаточноредкий случай, когда не существует простого способа сделать это ...

Позвольте мне повторить (по крайней мере, я думаю, что где-то это сказал): я могу выяснить, как сделать это вручную. Это не вопрос. Вопрос «НУЖНО ли мне делать это вручную?»Я не делал, когда у grp было только одно в строке, я мог использовать групповку. Теперь мне нужно все делать вручную? Если ответом будет «да», то я продолжу, но я бы не стал тратить свое время на реализацию множественных вложенных циклов (у меня есть несколько столбцов значений, несколько столбцов GRP и несколько значений в GRP), если яне нужно ...

Я добавил 2 ответа ниже, на случай, если нет простого группового решения ...

Ответы [ 3 ]

0 голосов
/ 07 октября 2019

ДЛЯ ПРИМЕРА: Если бы мне пришлось решать это самостоятельно, я мог бы использовать v2 выше с:

In [55]: means = pd.DataFrame(columns=['grp', 'value', 'value2'])                                       

In [56]: for grp in grps: 
    ...:     m = v2.groupby(grp).mean() 
    ...:     m = m[['value', 'value2']] 
    ...:     m['grp'] = grp 
    ...:     means = means.append(m.loc[1]) 

, который хотя бы избавился от цикла по столбцам ...

Я надеюсь, что есть решение, не связанное с этим ...

0 голосов
/ 07 октября 2019

Другой вариант (я полагаю, что люди могут голосовать? Если они хотят?), Это просто добавить дополнительные строки в v1, так:

In [85]: v11                                                                                            
Out[85]: 
  name  value   grp  value2
0    a     34     x      45
1    b     98  x, y       9
2    c      8     y     345
3    d      3     z       2
4   b1     98     x       9
5   b2     98     y       9

ТО я делаю обычные групповые ('grp') иЯ игнорирую группу 'x, y' ...

Out[86]: 
      value  value2
grp                
x        66      27
x, y     98       9
y        53     177
z         3       2

и проверяю, делаю ли я все это на копии, чтобы не испортить исходные данные ...

0 голосов
/ 07 октября 2019

Вы можете сделать что-то подобное с данными версии 2.

cols=['x','y','z']
df[cols].sum()
df[cols].mean()
df[cols].std()
df[cols].var()  

и т. Д. И т. П.

Вывод

для df[cols].sum()

x    2
y    2
z    1

для df[cols].mean()

x    0.50
y    0.50
z    0.25

Обновление

Вы можете использовать код ниже, чтобы получить сумму /среднее значение и т. д. для каждого из x, y & z

for col in cols:
    print(col,df[df[col]==1]['value'].sum())

Выход

x 132
y 106
z 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...