Подсчет групп одинаковых значений в одном столбце

У меня есть фрейм данных, содержащий столбцы с группами из 1 и -1. Каждый столбец может содержать любое количество единиц или -1, сгруппированных внутри каждого столбца, а также они могут начинаться с неопределенного количества NaN. Я хотел бы подсчитать общее количество значений в каждой группе, исключая NaN.

Пример фрейма данных приведен ниже:

NaN = float('nan')
df = pd.DataFrame({'col1':[1,1,1,1,-1,-1,-1,1,1],
                   'col2':[NaN, NaN, NaN, 1,1,-1,-1,-1,-1],
                   'col3':[NaN,NaN,NaN,NaN,NaN,1,1,1,-1]})

Я хотел бы, чтобы результат был другим фреймом данных, как показано ниже:

df =  pd.DataFrame({'col1':[4,4,4,4,3,3,3,2,2],
                    'col2':[NaN, NaN, NaN,2,2,4,4,4,4],
                    'col3': [NaN,NaN,NaN,NaN,NaN,3,3,3,1]})

Пожалуйста, предоставьте минимальный воспроизводимый пример как DataFrame/Series для ясности, а не список Python.

mozway 18.07.2024 17:22
Почему в 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
1
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Посмотрите этот пример:

import pandas as pd

df = pd.Series([1,1,1,-1])

count = df.value_counts().to_dict()

df = df.replace(count)
Ответ принят как подходящий

Предполагая DataFrame/Series, вы можете сгруппировать последовательные значения и использовать groupby.transform('size'):

df = pd.DataFrame({'col': [1,1,1,1,1,-1,-1,-1,-1,1,1,1]})
df['out'] = (df.groupby(df['col'].ne(df['col'].shift()).cumsum())
               .transform('size')
            )

Выход:

    col  out
0     1    5
1     1    5
2     1    5
3     1    5
4     1    5
5    -1    4
6    -1    4
7    -1    4
8    -1    4
9     1    3
10    1    3
11    1    3

Если ваши данные представляют собой список, а не для панд, используйте itertools.groupby / itertools.chain:

from itertools import groupby, chain

lst = [1,1,1,1,1,-1,-1,-1,-1,1,1,1]
out = list(chain.from_iterable([l:=len(list(g))]*l for _, g in groupby(lst)))

Выход:

[5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3]
несколько столбцов

Если у вас есть DataFrame с несколькими столбцами, вы можете преобразовать каждый столбец независимо с помощью применить и маски NaN:

NaN = float('nan')
df = pd.DataFrame({'col1':[1,1,1,1,-1,-1,-1,1,1],
                   'col2':[NaN, NaN, NaN, 1,1,-1,-1,-1,-1],
                   'col3':[NaN,NaN,NaN,NaN,NaN,1,1,1,-1]})

out = df.apply(lambda s: s.groupby(s.ne(s.shift()).cumsum())
                          .transform('size').mask(s.isna()))

Выход:

   col1  col2  col3
0     4   NaN   NaN
1     4   NaN   NaN
2     4   NaN   NaN
3     4   2.0   NaN
4     3   2.0   NaN
5     3   4.0   3.0
6     3   4.0   3.0
7     2   4.0   3.0
8     2   4.0   1.0

Спасибо за ответ. Какова была бы модификация кода, если бы я захотел применить его ко всему фрейму данных с различными группами единиц и -1? Как бы я не использовал часть df['col']?

Kevin 18.07.2024 17:39

Например, если бы у меня был фрейм данных df = pd.Dataframe({'col1':[1,1,1,1,1,-1,-1,-1,-1,1,1,1], 'col2 ':[1,1,-1,-1,-1,1,1,1,1]})

Kevin 18.07.2024 17:44

@Кевин, тогда какой ожидаемый результат? То же самое для каждого столбца? или у вас будет один выходной столбец, использующий все исходные столбцы в качестве группера? Обратите внимание, что ваш пример недействителен (списки имеют разную длину).

mozway 18.07.2024 17:47

Это будет другой фрейм данных с теми же столбцами df = {'col1':[5,5,5,5,5,4,4,4,4,3,3,3], 'col2':[2,2 ,3,3,3,4,4,4,4]}

Kevin 18.07.2024 17:50

Если вы хотите применить преобразование для каждого столбца независимо: df.apply(lambda s: s.groupby(s.ne(s.shift()).cumsum()).transform('size')).

mozway 18.07.2024 17:50

Спасибо! Что, если бы теперь у меня были столбцы, в некоторых из которых в начале было NaN, например df = {'col1': [NaN, NaN, NaN, NaN, 1,1,1,1,-1,-1,-1,- 1,-1], 'col2': [NaN, NaN,-1,-1,-1,1,1], 'col3':[1,1,-1,-1,-1]}. Мне бы хотелось того же решения, что и раньше, но записи с NaN не имели бы номера. Используя текущее решение, они заполняются значением «1».

Kevin 18.07.2024 18:03

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

mozway 18.07.2024 18:11

Извините, я сейчас отредактировал вопрос.

Kevin 18.07.2024 18:32

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

Как объединить несколько фреймов данных и суммировать общие значения в столбец
Как сопоставить прогнозы за несколько временных интервалов с фактическими значениями?
Суммирование перестановок в фрейме данных Pandas растет суперэкспоненциально
Найдите значение в столбце, который содержит список, возьмите другое значение из следующего столбца и поместите его в первую таблицу в новый столбец
Python pandas read_sas с параметром размера фрагмента завершается с ошибкой из-за несоответствия индекса
Как я могу заполнить значение на основе другого категориального столбца
Что означает: приведение данных Pandas к numpy dtype объекта. Проверьте входные данные с помощью np.asarray(data) и как это можно решить?
Как обобщить фрейм данных в пандах на основе значений
Отсутствует модуль Sklearn и вы не знаете, что использовать вместо него?
Как я могу эффективно фильтровать и агрегировать данные в Pandas DataFrame с несколькими условиями?