#python #dataframe #dictionary #join #merge
Вопрос:
итак, у меня есть два кадра данных, которые я пытаюсь объединить в один столбец. Однако этот общий столбец отличается между обоими кадрами данных, где значения в одном кадре данных являются полными именами, а значения в другом кадре данных являются сокращениями. Я пытаюсь создать своего рода словарь сопоставлений, который приравнивает имена к их аббревиатурам, чтобы фреймы данных могли быть непосредственно объединены этим общим столбцом. Я объясню подробнее ниже.
У меня есть этот фрейм данных (A):
Building Style CO2 NOx
---------------------------------------------------
Multi-Family A 34 55
Multi-Family B 43 44
Multi-Family C 33 35
Single-Family A 34 26
Single-Family B 22 26
Single-Family C 65 48
Single-Family D 55 74
Studio A 46 35
Studio B 54 67
Studio C 57 58
И затем у меня есть этот фрейм данных (B):
Building Style Zip_code Number
---------------------------------------
MF A 11111 4
MF A 22222 3
MF A 33333 2
MF B 11111 1
MF B 22222 1
MF C 22222 1
MF C 33333 6
SF A 11111 7
SF A 22222 5
SF B 44444 3
SF B 55555 8
SF B 66666 6
SF C 11111 9
SF C 22222 9
ST A 33333 3
ST A 44444 5
ST B 55555 5
ST B 66666 3
ST C 11111 2
ST C 22222 9
ST C 33333 1
Теперь я хочу создать следующий фрейм данных (C):
Zip_code CO2 NOx
-------------------------
11111 ? ?
22222 ? ?
33333 ? ?
44444 ? ?
55555 ? ?
66666 ? ?
Я объясню это дальше. У меня есть данные по зданиям, которые показывают выбросы CO2 и NOx для 3 стилей зданий, соответствующих 3 типам зданий (кадр данных A). Затем у меня есть данные, которые показывают, сколько домов каждого из этих типов находится в каждом из перечисленных почтовых индексов (Фрейм данных B). В конечном счете я хочу создать фрейм данных, который показывает общие выбросы для каждого почтового индекса, как для CO2, так и для NOx (Фрейм данных C). Идея получения фрейма данных C заключается в том, что я хочу создать фрейм данных, который затем может быть присоединен к шейп-файлу ГИС по почтовому индексу, чтобы затем я мог отобразить выбросы CO2 и NOx в каждом почтовом индексе, получив пустой шейп-файл zipcodes для присоединения. (Я понимаю, что картирование выбросов намного сложнее, чем это, но я сохраняю это простым для данного этапа моего проекта).
Поэтому я пытаюсь соединить фрейм данных A с фреймом данных B в столбце «Здание». Проблема, однако, заключается в том, что столбец «Здание» в кадре данных A содержит имена полностью, в то время как столбец «Здание» в кадре данных B содержит имена в виде сокращений. Я думаю, что мне нужно создать какой-то словарь, который сопоставит полное название с его аббревиатурой, на которую следует ссылаться, но я не уверен, как это сюда вписать.
Можно ли это сделать на python? Или это на самом деле намного сложнее, чем я себе это представляю? Я потратил много часов на то, чтобы понять, как объединить эти два кадра данных, но с каждым разом я все больше запутываюсь. У меня много проблем с концептуализацией того, как будет выглядеть этот код, даже если цель может показаться простой. Я был бы признателен за любую помощь или руководство в этом! Приношу извинения за то, что сделал эти кадры данных такими длинными, но я чувствовал, что необходимо отразить структуру/сложность данных.
Спасибо!
Ответ №1:
Это, безусловно, возможно. Вы действительно можете сначала превратить названия зданий в аббревиатуры, используя пользовательскую функцию, которая разбивается на дефис и принимает первую букву каждого слова. Затем вы можете объединить кадры данных на обоих Building
и Style
. Наконец-то вы можете groupby
на Zip-code
:
import pandas as pd
data1 = [ { "Building": "Multi-Family", "Style": "A", "CO2": 34, "NOx": 55 }, { "Building": "Multi-Family", "Style": "B", "CO2": 43, "NOx": 44 }, { "Building": "Multi-Family", "Style": "C", "CO2": 33, "NOx": 35 }, { "Building": "Single-Family", "Style": "A", "CO2": 34, "NOx": 26 }, { "Building": "Single-Family", "Style": "B", "CO2": 22, "NOx": 26 }, { "Building": "Single-Family", "Style": "C", "CO2": 65, "NOx": 48 }, { "Building": "Single-Family", "Style": "D", "CO2": 55, "NOx": 74 }, { "Building": "Studio", "Style": "A", "CO2": 46, "NOx": 35 }, { "Building": "Studio", "Style": "B", "CO2": 54, "NOx": 67 }, { "Building": "Studio", "Style": "C", "CO2": 57, "NOx": 58 } ]
data2 = [ { "Building": "MF", "Style": "A", "Zip_code": 11111, "Number": 4 }, { "Building": "MF", "Style": "A", "Zip_code": 22222, "Number": 3 }, { "Building": "MF", "Style": "A", "Zip_code": 33333, "Number": 2 }, { "Building": "MF", "Style": "B", "Zip_code": 11111, "Number": 1 }, { "Building": "MF", "Style": "B", "Zip_code": 22222, "Number": 1 }, { "Building": "MF", "Style": "C", "Zip_code": 22222, "Number": 1 }, { "Building": "MF", "Style": "C", "Zip_code": 33333, "Number": 6 }, { "Building": "SF", "Style": "A", "Zip_code": 11111, "Number": 7 }, { "Building": "SF", "Style": "A", "Zip_code": 22222, "Number": 5 }, { "Building": "SF", "Style": "B", "Zip_code": 44444, "Number": 3 }, { "Building": "SF", "Style": "B", "Zip_code": 55555, "Number": 8 }, { "Building": "SF", "Style": "B", "Zip_code": 66666, "Number": 6 }, { "Building": "SF", "Style": "C", "Zip_code": 11111, "Number": 9 }, { "Building": "SF", "Style": "C", "Zip_code": 22222, "Number": 9 }, { "Building": "ST", "Style": "A", "Zip_code": 33333, "Number": 3 }, { "Building": "ST", "Style": "A", "Zip_code": 44444, "Number": 5 }, { "Building": "ST", "Style": "B", "Zip_code": 55555, "Number": 5 }, { "Building": "ST", "Style": "B", "Zip_code": 66666, "Number": 3 }, { "Building": "ST", "Style": "C", "Zip_code": 11111, "Number": 2 }, { "Building": "ST", "Style": "C", "Zip_code": 22222, "Number": 9 }, { "Building": "ST", "Style": "C", "Zip_code": 33333, "Number": 1 } ]
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)
def shorten_buildings(text):
text = ''.join([i[0] for i in text.split('-')])
return text if text != 'S' else 'ST'
df1['Building'] = df1['Building'].apply(shorten_buildings)
df2 = df2.merge(df1, how='left', on=['Building','Style'])
df2['CO2'] = df2['Number'] * df2['CO2'] #total CO2
df2['NOx'] = df2['Number'] * df2['NOx'] #total NOx
df2.groupby(['Zip_code']).sum().drop('Number', axis=1)
Выход:
Почтовый индекс | CO2 | NOx |
---|---|---|
11111 | 1116 | 994 |
22222 | 1446 | 1328 |
33333 | 461 | 483 |
44444 | 296 | 253 |
55555 | 446 | 543 |
66666 | 294 | 357 |