Pandas groupby 0 значение, если не существует - PullRequest
0 голосов
/ 28 апреля 2018

У меня есть такой код

frame[frame['value_text'].str.match('Type 2')  | frame['value_text'].str.match('Type II diabetes')].groupby(['value_text','gender'])['value_text'].count()

, который возвращает серию, подобную

value_text            gender      count
type 2                  M           4
type 2 without...       M           4
                        F           3

что я хочу это

 value_text               gender      count
    type 2                  M           4
                            F           0
    type 2 without...       M           4
                            F           3

Я хочу включить подсчет для всех полов, хотя в кадре данных нет записей. как я могу это сделать?

Ответы [ 4 ]

0 голосов
/ 03 мая 2018

Категориальные данные были введены в pandas специально для этой цели.

В действительности, groupby операции с категориальными данными автоматически вычисляют декартово произведение.

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

import pandas as pd

df = pd.DataFrame({'value_text': ['type2', 'type2 without', 'type2'],
                   'gender': ['M', 'F', 'M'],
                   'value': [1, 2, 3]})

df['gender'] = df['gender'].astype('category')

res = df.groupby(['value_text', 'gender']).count()\
        .fillna(0).astype(int)\
        .reset_index()

print(res)

      value_text gender  value
0          type2      F      0
1          type2      M      2
2  type2 without      F      1
3  type2 without      M      0
0 голосов
/ 28 апреля 2018

Самый простой способ сделать это с помощью pd.crosstab, а затем stack:

# save your filtered dataframe as an intermediate result, for convenience
type2 = frame[frame.value_text.str.match('Type 2|Type II diabetes')]

pd.crosstab(type2.value_text, type2.gender).stack()
0 голосов
/ 28 апреля 2018

Помните, всякий раз, когда вы хотите, чтобы определенный список индексировал / формировал ваши данные. Pivot , кросс-таблица , стек , unstack не являются надежными, поскольку они сильно зависят от входных данных. Например, если «M» никогда не отображается в какой-либо строке ввода, вы не увидите «M», независимо от того, как вы поворачиваете / разбрасываете свой результат. Проблема такого рода в том, где reindex () светит.

Предположим, что ваш предварительно обработанный кадр сохраняется как df :

  mdx1 = pd.MultiIndex.from_product([df.index.levels[0], ['M', 'F']])
  df.reindex(mdx1).fillna(0, downcast='infer')

С другой стороны, если вы хотите, чтобы все возможные значения уровня 1 отображались на всех уровнях 0, сделайте следующее:

  mdx1 = pd.MultiIndex.from_product(df.index.levels)
  df.reindex(mdx1).fillna(0, downcast='infer')

Это можно легко распространить на кадры данных с более чем двухуровневыми индексами.

Обновление: use Категориальный тип данных может решить проблемы, связанные с функциями, похожими на сводные.

0 голосов
/ 28 апреля 2018

Попробуйте добавить .unstack().fillna(0).stack() к вашей текущей строке, например:

frame[frame['value_text'].str.match('Type 2')  |
      frame['value_text'].str.match('Type II diabetes')]\
.groupby(['value_text','gender'])['value_text'].count()\
.unstack().fillna(0).stack()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...