Класс Groupby и подсчет пропущенных значений в элементах - PullRequest
0 голосов
/ 27 декабря 2018

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

Что я хочу сделать?

У меня естьвот такой кадр данных

CLASS FEATURE1 FEATURE2 FEATURE3
  X      A       NaN      NaN
  X     NaN       A       NaN
  B      A        A        A

Я хочу сгруппировать по метке ( CLASS ) и отобразить количество значений NaN, которые учитываются в каждой функции, чтобы это выглядело следующим образом.Цель этого состоит в том, чтобы получить общее представление о том, как пропущенные значения распределяются по различным классам.

CLASS FEATURE1 FEATURE2 FEATURE3
  X      1        1        2
  B      0        0        0

Я знаю, как получить сумму ненулевых -значений - df.groupby['CLASS'].count()

Есть ли что-то похожее для NaN -Values?

Я пытался вычесть count () из size (), но он вернул неформатированный вывод, заполненныйзначение NaN

Ответы [ 3 ]

0 голосов
/ 27 декабря 2018

Вы можете использовать set_index и sum:

df.set_index('CLASS').isna().sum(level=0)

Выход:

       FEATURE1  FEATURE2  FEATURE3
CLASS                              
X           1.0       1.0       2.0
B           0.0       0.0       0.0
0 голосов
/ 27 декабря 2018

Используя разность между count и size

g=df.groupby('CLASS')

-g.count().sub(g.size(),0)

          FEATURE1  FEATURE2  FEATURE3
CLASS                              
B             0         0         0
X             1         1         2

И мы можем преобразовать этот вопрос в более общий вопрос, как посчитать, сколько NaN в кадре данных с для цикла for

pd.DataFrame({x: y.isna().sum()for x , y in g }).T.drop('CLASS',1)
Out[468]: 
   FEATURE1  FEATURE2  FEATURE3
B         0         0         0
X         1         1         2
0 голосов
/ 27 декабря 2018

Вычислите маску с помощью isna, затем сгруппируйте и найдите сумму:

df.drop('CLASS', 1).isna().groupby(df.CLASS, sort=False).sum().reset_index()

  CLASS  FEATURE1  FEATURE2  FEATURE3
0     X       1.0       1.0       2.0
1     B       0.0       0.0       0.0

Другой вариант - вычесть size из count, используя rsub вдоль0 th ось для вычитания, выровненного по индексу:

df.groupby('CLASS').count().rsub(df.groupby('CLASS').size(), axis=0)

Или

g = df.groupby('CLASS')
g.count().rsub(g.size(), axis=0)

       FEATURE1  FEATURE2  FEATURE3
CLASS                              
B             0         0         0
X             1         1         2

Есть довольноНесколько хороших ответов, поэтому вот несколько timeits для вашего прочтения:

df_ = df
df = pd.concat([df_] * 10000)

%timeit df.drop('CLASS', 1).isna().groupby(df.CLASS, sort=False).sum()
%timeit df.set_index('CLASS').isna().sum(level=0)    
%%timeit
g = df.groupby('CLASS')
g.count().rsub(g.size(), axis=0)

11.8 ms ± 108 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.47 ms ± 379 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
6.54 ms ± 81.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

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

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