Группировка столбцов, если их значения совпадают

Я новичок в Python и у меня возник вопрос, буду признателен, если кто-нибудь может помочь:

У меня есть набор данных, который выглядит так:

Химия1Химическое значение1Химия2Химическое значение2Химия3Химическое значение3
Монооксид углерода32Углекислый газ32Углерод45
Сера32Сера32Сера45
Углерод32Углерод32Железо45
Углерод32Железо32Железо45

Если Chem1 равно Chem2 и/или Chem 3, я хочу добавить соответствующее значение ChemValue. Итак, я получаю такой набор данных:

Химия1Химическое значение1Химия2Химическое значение2Химия3Химическое значение3
Монооксид углерода32Углекислый газ32Углерод45
Сера109----
Углерод64--Железо45
Углерод32Железо77--

Затем я хочу просто получить Chem с самым высоким соответствующим ChemValue (это нормально, если я не получу приведенную выше таблицу в качестве посредника, просто отлично с получением максимального совокупного Chem):

Высшая хим.
Монооксид углерода
Сера
Углерод
Железо

Как я могу сделать это в Python?

#here is the first dataset

data = {'Chem1': ['Carbon Monoxide','Sulfur','Carbon','Carbon'], 'ChemValue1': [32,32,32,32],'Chem2': ['Carbon Dioxide','Sulfur','Carbon','Iron'],'ChemValue2': [32,32,32,32],'Chem3': ['Carbon','Sulfur','Iron','Iron'],'ChemValue3': [45,45,45,45]}  
df = pd.DataFrame(data)

Разве сера не самая высокая в 109, у вас на столе угарный газ наверху

Kenan 09.04.2022 04:43
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
1
1
30
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Это требует больше работы, чем мы думаем, 2-й df может быть выполнен, пока мы получаем 1-й df

s = pd.wide_to_long(df.reset_index(),stubnames=['Chem','ChemValue'],i = 'index',j='v').reset_index()
#use pd.wide_to_long melt the df from row to column
secdf = s.groupby(['index','Chem'])['ChemValue'].sum().reset_index(level=0).groupby('index')['ChemValue'].idxmax()
# then we can do groupby combine the same value and get the max id of index 
Out[274]:
index
0    Carbon
1    Sulfur
2    Carbon
3      Iron
Name: ChemValue, dtype: object
s = s.groupby(['index','Chem']).agg({'ChemValue':'sum','v':'first'}).reset_index(level=1).set_index('v',append=True).unstack().sort_index(axis=1,level=1)
s.columns = s.columns.map('{0[0]}{0[1]}'.format)
s
Out[288]: 
                 Chem1  ChemValue1  ...   Chem3  ChemValue3
index                               ...                    
0      Carbon Monoxide        32.0  ...  Carbon        45.0
1               Sulfur       109.0  ...     NaN         NaN
2               Carbon        64.0  ...    Iron        45.0
3               Carbon        32.0  ...     NaN         NaN
[4 rows x 6 columns]

Огромное спасибо! Получает оба набора данных, которые мне нужны, и хорошо масштабируется для большого количества строк/столбцов!

MB1001 09.04.2022 06:04

Это должно получить окончательный результат, который задает вопрос:

import pandas as pd
data = {'Chem1': ['Carbon Monoxide','Sulfur','Carbon','Carbon'], 'ChemValue1': [32,32,32,32],'Chem2': ['Carbon Dioxide','Sulfur','Carbon','Iron'],'ChemValue2': [32,32,32,32],'Chem3': ['Carbon','Sulfur','Iron','Iron'],'ChemValue3': [45,45,45,45]}  
df = pd.DataFrame(data)
print(df)

from collections import defaultdict
highestChem, highestChemValue = [], []
def aggregateChems(x):
    dct = defaultdict(int)
    for k, v in (('Chem1', 'ChemValue1'), ('Chem2', 'ChemValue2'), ('Chem3', 'ChemValue3')):
        dct[x[k]] += x[v]
    highestChem.append(max(dct, key=lambda x: dct[x]))
    highestChemValue.append(dct[highestChem[-1]])
df.apply(aggregateChems, axis = 1)

df2 = pd.DataFrame({'HighestChem' : highestChem, 'ChemValue' : highestChemValue})
print(f"\n{df2}")

df3 = df2['HighestChem'].to_frame()
print(f"\n{df3}")

Выход:

             Chem1  ChemValue1           Chem2  ChemValue2   Chem3  ChemValue3
0  Carbon Monoxide          32  Carbon Dioxide          32  Carbon          45
1           Sulfur          32          Sulfur          32  Sulfur          45
2           Carbon          32          Carbon          32    Iron          45
3           Carbon          32            Iron          32    Iron          45

  HighestChem  ChemValue
0      Carbon         45
1      Sulfur        109
2      Carbon         64
3        Iron         77

  HighestChem
0      Carbon
1      Sulfur
2      Carbon
3        Iron

Спасибо! Хотел бы я выбрать более одного правильного ответа, это очень элегантно :)

MB1001 09.04.2022 06:04

Я выбрал более ручной подход, который отлично работает для 3 Chem, но плохо масштабируется.

c12 = df['Chem1'].eq(df['Chem2'])
c13 = df['Chem1'].eq(df['Chem3'])
df.loc[c12, 'ChemValue1'] = df['ChemValue1'] + df['ChemValue2']
df.loc[c13, 'ChemValue1'] = df['ChemValue1'] + df['ChemValue3']

c23 = df['Chem2'].eq(df['Chem3'])
df.loc[c23, 'ChemValue2'] = df['ChemValue2'] + df['ChemValue3']
pd.wide_to_long(df.reset_index(),stubnames=['Chem','ChemValue'],i = 'index',j='k').reset_index(drop=True)
               Chem  ChemValue
0   Carbon Monoxide         32
1            Sulfur        109
2            Carbon         64
3            Carbon         32
4    Carbon Dioxide         32
5            Sulfur         77
6            Carbon         32
7              Iron         77
8            Carbon         45
9            Sulfur         45
10             Iron         45
11             Iron         45

Спасибо за ваш ответ! Да, в моем фактическом наборе данных у меня больше столбцов (10+).

MB1001 09.04.2022 06:05

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