Метод value_counts() Panda непоследовательно подсчитывает пропущенные значения

Пожалуйста, рассмотрите этот простой фрейм данных:

df = pd.DataFrame({'x': [1, 2, 3, 4, 10]}, index = range(5))

df:
    x
0   1
1   2
2   3
3   4
4   10

Некоторые индексы:

ff_idx = [1, 2]

sd_idx= [3, 4]

Один из способов создания нового столбца путем фильтрации df на основе приведенных выше индексов:

df['ff_sd_indicator'] = np.nan
df['ff_sd_indicator'][df.index.isin(ff_idx)] = 'ff_count' 
df['ff_sd_indicator'][df.index.isin(sd_idx)] = 'sd_count' 

Другой способ сделать то же самое:

df['ff_sd_indicator2'] = np.select([df.index.isin(ff_idx) , df.index.isin(sd_idx)], ['ff_count','sd_count' ], default=np.nan)

Обратите внимание: хотя значения ff_sd_indicator и ff_sd_indicator2, естественно, одинаковы, пропущенные значения печатаются по-разному (NaN или nan):

df: 

    x   ff_sd_indicator ff_sd_indicator2
0   1   NaN         nan
1   2   ff_count    ff_count
2   3   ff_count    ff_count
3   4   sd_count    sd_count
4   10  sd_count    sd_count

Меня не волнуют разные отпечатки, но, что удивительно, пропущенные значения не отображаются в выводе:

df['ff_sd_indicator'].value_counts()

который:

ff_sd_indicator
ff_count    2
sd_count    2

Но они появляются в выводе:

df['ff_sd_indicator2'].value_counts()

который:

ff_sd_indicator2
ff_count    2
sd_count    2
nan         1

Итак, что здесь происходит с тем, что value_counts() не считает пропущенные значения в ff_sd_indicator, хотя они были созданы тем же np.nan, что и недостающие значения в ff_sd_indicator2?

Редактировать: df.info() :

RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
 #   Column            Non-Null Count  Dtype 
---  ------            --------------  ----- 
 0   x                 5 non-null      int64 
 1   ff_sd_indicator   5 non-null      object
 2   ff_sd_indicator2  5 non-null      object

Каковы типы двух столбцов? Я считаю, что у вас есть столбец типа объекта и столбец строкового типа.

akuiper 12.07.2024 19:29

@akuiper, нет, оба являются объектами. Отредактировал вопрос.

Saeed 12.07.2024 19:44
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По умолчанию value_counts отбрасывает NaN, чего можно избежать, установив dropna=False:

df['ff_sd_indicator'].value_counts(dropna=False)

ff_sd_indicator
ff_count    2
sd_count    2
NaN         1
Name: count, dtype: int64

Если вы проверите вывод:

np.select([df.index.isin(ff_idx) , df.index.isin(sd_idx)],
          ['ff_count','sd_count'], default=np.nan)

Однако вы увидите, что у вас не NaN, а строка:

array(['nan', 'ff_count', 'ff_count', 'sd_count', 'sd_count'],
      dtype='<U32')

Таким образом, значение не удаляется автоматически.

Ааа, ты совершенно прав. Но почему np.select создает значения по умолчанию в виде строки, в то время как пользователь указал default=np.nan (то есть с плавающей точкой), хотя он мог бы сделать default='nan', если бы ему нужна строка nan? Разве это не недостаток функции np.select?

Saeed 12.07.2024 19:48

@Saeed, потому что массивы numpy имеют однородный тип dtype, когда несовместимые типы dtype смешаны, numpy может попытаться привести к понижению. Точно так же, если вы присвоите число с плавающей запятой целочисленному массиву, будет использоваться только целая часть. Обратите внимание, что вы можете создавать массивы объектов, но это должно быть сделано явно.

mozway 12.07.2024 19:53

Кстати, меня смутило то, что я пытался заменить эти пропущенные значения на 0 на df['ff_sd_indicator2'].fillna(0), но, конечно, этого не получалось, потому что это были строки nan.

Saeed 12.07.2024 19:56

Другие вопросы по теме