Получение результата группировки по нескольким столбцам и подсчета непосредственно в моем фрейме данных - PullRequest
0 голосов
/ 29 января 2019

У меня есть датафрейм (пример с игрушкой ниже из другого поста), который вы можете сгенерировать с помощью кода ниже;Я хотел бы сгруппировать по столбцам 'col1' и 'col2' и подсчитать количество вхождений в каждой группе, как в этом примере: Как посчитать количество строк в группе (и другую статистику) в группе панд по?

Но чтобы включить результат непосредственно в мой фрейм данных, как в этом примере (где есть только один столбец для группировки): Панды, сгруппировать по количеству и добавить количество к исходному фрейму данных?

Я пытался:

df['count'] = df.groupby(['col1','col2']).transform('count')

И:

df['count'] = df.groupby(['col1','col2'])[['col1','col2']].transform('count')

Но я получаю одну и ту же ошибку оба раза:

ValueError: Length of passed values is 10, index implies 0 

Любая идея, как я мог бы обойти это без необходимости объединить результат с моим исходным кадром данных?В R dplyr это было бы довольно просто с groupby, mutate и n() ....

Пример игрушки:

  col1 col2  col3  col4  col5  col6
0    A    B  0.20 -0.61 -0.49  1.49
1    A    B -1.53 -1.01 -0.39  1.82
2    A    B -0.44  0.27  0.72  0.11
3    A    B  0.28 -1.32  0.38  0.18
4    C    D  0.12  0.59  0.81  0.66
5    C    D -0.13 -1.65 -1.64  0.50
6    C    D -1.42 -0.11 -0.18 -0.44
7    E    F -0.00  1.42 -0.26  1.17
8    E    F  0.91 -0.47  1.35 -0.34
9    G    H  1.48 -0.63 -1.14  0.17

Код для генерации кадра данных игрушки:

import numpy as np
import pandas as pd 

keys = np.array([
   ['A', 'B'],
   ['A', 'B'],
     ['A', 'B'],
  ['A', 'B'],
     ['C', 'D'],
   ['C', 'D'],
   ['C', 'D'],
   ['E', 'F'],
   ['E', 'F'],
   ['G', 'H'] 
   ])

df = pd.DataFrame(
np.hstack([keys,np.random.randn(10,4).round(2)]), 
columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6']
)

df[['col3', 'col4', 'col5', 'col6']] = df[['col3', 'col4', 
'col5','col6']].astype(float)

Ответы [ 2 ]

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

Если вы сложите () результат вашего groupby (), у вас будет результат, который соответствует длине строк вашего DataFrame.Затем с помощью reset_index () он будет соответствовать предыдущему фрейму данных.

df['count'] = df.groupby(['col1', 'col2']).count().stack().reset_index()[0]

Даст вам ...

import numpy as np
import pandas as pd 

keys = np.array([
   ['A', 'B'],
   ['A', 'B'],
     ['A', 'B'],
  ['A', 'B'],
     ['C', 'D'],
   ['C', 'D'],
   ['C', 'D'],
   ['E', 'F'],
   ['E', 'F'],
   ['G', 'H'] 
   ])

df = pd.DataFrame(
np.hstack([keys,np.random.randn(10,4).round(2)]), 
columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6']
)

df[['col3', 'col4', 'col5', 'col6']] = df[['col3', 'col4', 
'col5','col6']].astype(float)

df_count = df.groupby(['col1', 'col2']).count()
print(df_count)
#            col3  col4  col5  col6
# col1 col2                        
# A    B        4     4     4     4
# C    D        3     3     3     3
# E    F        2     2     2     2
# G    H        1     1     1     1
stacked_count = df_count.stack()
print(stacked_count)
# col1  col2      
# A     B     col3    4
#             col4    4
#             col5    4
#             col6    4
# C     D     col3    3
#             col4    3
#             col5    3
#             col6    3
# E     F     col3    2
#             col4    2
#             col5    2
#             col6    2
# G     H     col3    1
#             col4    1
#             col5    1
#             col6    1
# dtype: int64

ndf = stacked_count.reset_index()[0]
print(ndf)
# 0     4
# 1     4
# 2     4
# 3     4
# 4     3
# 5     3
# 6     3
# 7     3
# 8     2
# 9     2
# 10    2
# 11    2
# 12    1
# 13    1
# 14    1
# 15    1
# Name: 0, dtype: int64

df['count'] = ndf
print(df)
#   col1 col2  col3  col4  col5  col6  count
# 0    A    B -0.81 -1.39  0.07  0.71      4
# 1    A    B -1.37  1.72 -2.04  0.83      4
# 2    A    B -1.81 -0.53 -1.27 -0.83      4
# 3    A    B -1.05 -0.06 -1.78  0.81      4
# 4    C    D -1.40  0.36  0.94  1.90      3
# 5    C    D  0.65  0.49 -1.78  0.10      3
# 6    C    D -0.57 -0.08  1.11 -0.73      3
# 7    E    F  0.37  0.99 -1.62 -1.26      3
# 8    E    F  0.09 -0.03  1.27  0.80      2
# 9    G    H  0.26  0.71  0.05  0.48      2
0 голосов
/ 29 января 2019

РЕДАКТИРОВАТЬ

После комментария @Alollz код можно уменьшить до одной строки без объединения: df['count'] = df.groupby(['col1', 'col2'])['col1'].transform('size')


Ответ перед редактированием

Обходной путь будет заключаться в создании столбца concatenated перед применением groupby.

После этого вы можете использовать функцию size внутри вашего transformметод.

Возможно, не самый элегантный, но работает.

Код

# make a concatenated column 
df['concat'] = df.col1 + df.col2

# perform the transformation asked
df['count'] = df.groupby(['concat'])['concat'].transform('size')

# drop the concat column
df.drop('concat', axis=1, inplace=True)


    col1col2col3    col4    col5    col6    count
0   A   B   -0.62   0.09    0.92    1.45    4
1   A   B   1.49    0.31    -0.40   -0.99   4
2   A   B   -1.30   1.01    -0.31   -0.32   4
3   A   B   -0.05   0.32    -1.45   -0.54   4
4   C   D   -1.30   1.26    1.80    0.50    3
5   C   D   0.75    0.13    0.49    -2.37   3
6   C   D   1.05    -0.96   -0.44   -1.00   3
7   E   F   0.31    -0.93   -1.78   -1.49   2
8   E   F   -0.23   0.30    0.77    1.46    2
9   G   H   -0.67   0.88    -0.26   -1.09   1

Надеюсь, это поможет.

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