Подсчитать наиболее частую группу со значениями Nan - PullRequest
0 голосов
/ 02 июля 2018

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

dfgrouped = data[COLUMNS.copy()].groupby(['Var1','Var2']).agg(lambda x: stats.mode(x)[1])

Этот код работает, но не работает со столбцами, имеющими значения Nan, поскольку значения NaN являются плавающими, а другие - str. Итак, эта ошибка показана:

'<' not supported between instances of 'float' and 'str'

Я хотел бы опустить значения NaN и режим подсчета для остальных. Так что str (x) не является решением. И scipy.stats.mode (x, nan_policy = 'omit') не работает ни с ошибкой:

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Не могли бы вы дать мне совет, как с этим бороться. Спасибо

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

nan имеет тип float, а np.nan == np.nan также False. Если вам нужно сгруппировать их, вы можете попробовать что-то вроде этого:

# First replace nan values with something like 'Unavailable'
data.fillna('Unavailable', inplace=True)
# Then re-run your code
dfgrouped = data[COLUMNS.copy()].groupby(['Var1','Var2']).agg(lambda x: stats.mode(x)[1])

Это объединит все недоступные вместе в группу. Надеюсь, это поможет

0 голосов
/ 02 июля 2018

дропна первая

Вы можете dropna в качестве начального шага перед выполнением groupby. Если вы попытаетесь набрать dropna в агрегации, то группа со всеми значениями NaN может выдать ошибку с stats.mode.

Вот минимальный пример:

import pandas as pd
import numpy as np
from scipy import stats

df = pd.DataFrame([[1, 2, np.nan], [1, 2, 'hello'], [1, 2, np.nan],
                   [5, 6, 'next'], [5, 6, np.nan], [5, 6, 'next'],
                   [7, 8, np.nan], [7, 8, np.nan], [7, 8, np.nan]],
                  columns=['Var1', 'Var2', 'Value'])

res = df.dropna(subset=['Value'])\
        .groupby(['Var1', 'Var2'])\
        .agg(lambda x: stats.mode(x)[1][0])

print(res)

           Value
Var1 Var2       
1    2         1
5    6         2

catch IndexError

Если вам нужно сохранить группы со всеми значениями NaN, вы можете поймать IndexError:

def mode_calc(x):
    try:
        return stats.mode(x.dropna())[1][0]
    except IndexError:
        return np.nan

res = df.groupby(['Var1', 'Var2'])\
        .agg(mode_calc)

print(res)

           Value
Var1 Var2       
1    2       1.0
5    6       2.0
7    8       NaN
0 голосов
/ 02 июля 2018

Мне кажется, нужно dropna для удаления NaN s:

dfgrouped = data[COLUMNS.copy()].groupby(['Var1','Var2']).agg(lambda x: stats.mode(x.dropna())[1])

При необходимости установите NaN с для всех групп NaN:

dfgrouped = (data[COLUMNS.copy()]
              .groupby(['Var1','Var2'])
              .agg(lambda x: None if x.isnull().all() else stats.mode(x.dropna())[1]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...