Группировка панд в нескольких измерениях, одна из которых содержит значения None [duplicate]

60
задан Andy Hayden 25 August 2013 в 18:11
поделиться

6 ответов

Это , упомянутое в разделе «Отсутствующие данные» документов :

Группы NA в GroupBy автоматически исключаются. Это поведение согласуется, например, с R.

. Один способ заключается в использовании заполнителя перед выполнением groupby (например, -1):

In [11]: df.fillna(-1)
Out[11]: 
   a   b
0  1   4
1  2  -1
2  3   6

In [12]: df.fillna(-1).groupby('b').sum()
Out[12]: 
    a
b    
-1  2
4   1
6   3

Тем не менее, это выглядит довольно ужасно ... возможно, должен быть включен вариант NaN в groupby (см. этот вопрос github ), который использует тот же взлом для замены места.

67
ответ дан Andy Hayden 24 August 2018 в 03:49
поделиться

Я уже ответил на это, но почему-то ответ был преобразован в комментарий. Тем не менее, это наиболее эффективное решение:

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

dfgrouped = df.groupby(['b']).a.agg(['sum','size','count'])

dfgrouped['sum'][dfgrouped['size']!=dfgrouped['count']] = None

Когда они отличаются, вы можете установить значение обратно в None для результат функции агрегации для этой группы.

1
ответ дан Brian Preslopsky 24 August 2018 в 03:49
поделиться

Хотя по умолчанию в групповых агрегациях нет функции skipna, есть простой и чистый способ:

def custom_mean(df):
    return df.mean(skipna=False)

group.agg({"your_col_name_to_be_aggregated":custom_mean})

Вот и все!

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

Ответ найден в документе doc .

0
ответ дан c-a 24 August 2018 в 03:49
поделиться

Я не могу добавить комментарий к M. Kiewisch, так как у меня недостаточно очков репутации (есть только 41, но вам нужно больше 50 комментариев).

Во всяком случае, просто хочу указать что решение М. Кивиша не работает так, как есть, и может потребоваться больше настроек. Рассмотрим, например,

>>> df = pd.DataFrame({'a': [1, 2, 3, 5], 'b': [4, np.NaN, 6, 4]})
>>> df
   a    b
0  1  4.0
1  2  NaN
2  3  6.0
3  5  4.0
>>> df.groupby(['b']).sum()
     a
b
4.0  6
6.0  3
>>> df.astype(str).groupby(['b']).sum()
      a
b
4.0  15
6.0   3
nan   2

, который показывает, что для группы b = 4.0 соответствующее значение равно 15 вместо 6. Здесь оно просто объединяет 1 и 5 как строки вместо того, чтобы добавлять их в виде чисел.

6
ответ дан Kamaraju Kusumanchi 24 August 2018 в 03:49
поделиться

Древняя тема, если кто-то все еще спотыкается об этом - другое обходное решение - преобразовать через .astype (str) в строку перед группировкой. Это сохранит NaN.

in:

df = pd.DataFrame({'a': ['1', '2', '3'], 'b': ['4', np.NaN, '6']}) df.astype(str).groupby(['b']).sum()

out:
    a
b   
4   1
6   3
nan 2
12
ответ дан M. Kiewisch 24 August 2018 в 03:49
поделиться

Одна небольшая точка для решения Энди Хейдена - это не работает (больше?), потому что np.nan == np.nan дает False, поэтому функция replace фактически ничего не делает.

Что работал для меня:

df['b'] = df['b'].apply(lambda x: x if not np.isnan(x) else -1)

(По крайней мере, это поведение для Pandas 0.19.2. Извините, что добавьте его как другой ответ, у меня недостаточно репутации для комментариев.)

5
ответ дан Tuetschek 24 August 2018 в 03:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: