Объединение категориальных переменных в одну переменную в python 3 pandas

У меня есть фрейм данных pandas с 4 столбцами. так

ID  col1                        col2                col3
1   Strongly Positive   Strongly Positive   Weekly Positive
2   Strongly Positive   Strongly Positive   Neutral
3   Strongly Negative   Strongly Negative   Weekly Negative
4   Weekly Negative      Strongly Negative  Neutral
5   Neutral              Neutral            Neutral
6   Strongly Positive   Strongly Negative   Strongly Negative
7   Strongly Negative   Weekly Positive     Neutral
8   Neutral               Weekly Negative   Weekly Positive

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

  1. Если весь столбец имеет положительные значения или хотя бы одно положительное и два нейтральных значения, то агрегируйте эту запись в новом столбце как положительную.
  2. Если все три столбца имеют нейтральное значение, отметьте их как нейтральные.
  3. Если все столбцы имеют отрицательные значения или хотя бы одно отрицательное и два нейтральных значения, пометьте их как отрицательные.
  4. Если присутствуют как положительные, так и отрицательные значения, отметьте их как оба под положительным я подразумеваю либо сильный, либо еженедельный положительный результат, и то же самое для отрицательного.

Мне нужно, чтобы окончательный фрейм данных был таким

ID  col1                  col2          col3        Aggregated_Col
1   Strongly Positive  Strongly Positive Weekly Positive    Positive
2   Strongly Positive  Strongly Positive Neutral            Positive
3   Strongly Negative  Strongly Negative Weekly Negative    Negative
4   Weekly Negative    Strongly Negative Neutral            Negative
5   Neutral            Neutral       Neutral                Neutral
6   Strongly Positive  Strongly Negative Strongly Negative  Both
7   Strongly Negative  Weekly Positive   Neutral            Both
8   Neutral Weekly     Negative      Weekly Positive        Both

Не в состоянии придумать логику

ID  col1                  col2          col3        Aggregated_Col
1   Strongly Positive  Strongly Positive Weekly Positive    Positive
2   Strongly Positive  Strongly Positive Neutral            Positive
3   Strongly Negative  Strongly Negative Weekly Negative    Negative
4   Weekly Negative    Strongly Negative Neutral            Negative
5   Neutral            Neutral       Neutral            Neutral
6   Strongly Positive  Strongly Negative Strongly Negative  Both
7   Strongly Negative  Weekly Positive   Neutral            Both
8   Neutral Weekly     Negative      Weekly Positive    Both
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
454
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

recode = {"Strongly Positive": 2, "Weakly Positive": 1, "Neutral": 0, "Weakly Negative": -1, "Strongly Negative": -2}

Затем вы можете написать такую ​​функцию:

def interpret(values):
  if min(values) >= 0:
    return 1
  elif ...

и вызвать его с помощью df.apply(interpret, axis=1)

У вас есть 3 столбца, поэтому вы можете использовать

DF.apply(YourCustomFunction, axis=1)

Ось 1 сообщает, что вы хотите выполнить операцию над строками. Напишите свою пользовательскую логику в виде функции:

def MyFunction(x):
    if condition1:
        Do something
    elif condition2:
        Do something
    ........

Так проходит

DF['NewCol'] = DF.apply(MyFunction, axis=1)

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

Вы можете замаскировать соответствующие элементы следующим образом:

# set index as ID:
df.set_index('ID', inplace=True)

has_pos = df.apply(lambda x: x.str.contains('Positive')).any(axis=1)
has_neg = df.apply(lambda x: x.str.contains('Negative')).any(axis=1)
has_both = has_pos & has_neg

# update
df['Agg_Col'] = 'Neutral'
df.loc[has_pos,'Agg_Col'] = 'Positive'
df.loc[has_neg,'Agg_Col'] = 'Negative'

df.loc[has_both,'Agg_Col'] = 'Both'
Ответ принят как подходящий

Интересное нестандартное решение

from numpy.core.defchararray import find

a = df.to_numpy().astype(str)
b = np.select([find(a, 'Pos') >= 0, find(a, 'Neg') >= 0], [1, -1], 0)

c = np.select(
    [(b == 0).all(1), (b >=0).all(1), (b <= 0).all(1)],
    ['Neutral', 'Positive', 'Negative'],
    'Both'
)

df.assign(Agg=c)

                 col1               col2               col3       Agg
ID                                                                   
1   Strongly Positive  Strongly Positive    Weekly Positive  Positive
2   Strongly Positive  Strongly Positive            Neutral  Positive
3   Strongly Negative  Strongly Negative    Weekly Negative  Negative
4     Weekly Negative  Strongly Negative            Neutral  Negative
5             Neutral            Neutral            Neutral   Neutral
6   Strongly Positive  Strongly Negative  Strongly Negative      Both
7   Strongly Negative    Weekly Positive            Neutral      Both
8             Neutral    Weekly Negative    Weekly Positive      Both

Немного другой взгляд

from numpy.core.defchararray import find

a = df.to_numpy().astype(str)
b = np.select([find(a, 'Pos') >= 0, find(a, 'Neg') >= 0], [1, -1], 0)

m = {
    (0, 0): 'Neutral', (1, -1): 'Both',
    (1, 1): 'Positive', (1, 0): 'Positive',
    (-1, -1): 'Negative', (0, -1): 'Negative',
}

df.assign(Agg=[*map(m.get, zip(b.max(1), b.min(1)))])

                 col1               col2               col3       Agg
ID                                                                   
1   Strongly Positive  Strongly Positive    Weekly Positive  Positive
2   Strongly Positive  Strongly Positive            Neutral  Positive
3   Strongly Negative  Strongly Negative    Weekly Negative  Negative
4     Weekly Negative  Strongly Negative            Neutral  Negative
5             Neutral            Neutral            Neutral   Neutral
6   Strongly Positive  Strongly Negative  Strongly Negative      Both
7   Strongly Negative    Weekly Positive            Neutral      Both
8             Neutral    Weekly Negative    Weekly Positive      Both

Я столкнулся с проблемой в df.to_numpy(). Поэтому панды должны быть обновлены до 0.24 или выше.

Basudev 31.05.2019 15:19

Нет, просто используйте df.values.

piRSquared 31.05.2019 15:20

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