Изучение новейшей истории электростанций внутреннего сгорания в Нидерландах.
Часть 2. Страшный на первый взгляд, но пушистый внутри. Обратите внимание, почему вы должны использовать многоиндексные (иерархические) фреймы данных.
Ниже я кратко представляю свои размышления о мультииндексных фреймах данных. За результатами переходите к части 1. За кодом — сюда. Если вы ищете хороший вводный учебник, я настоятельно рекомендую вам это или это.
Если вы, как и я, интересуетесь анализом временных рядов, вам всегда будет сложно найти способ добавить измерение времени наиболее репрезентативным образом. На самом деле, я до сих пор помню свою первую попытку исследовать набор данных временных рядов значительного размера, сколько разочарований мне потребовалось, чтобы решить, что делать, чтобы не потерять связь с временными особенностями данных. Что, если бы я сказал вам, что теперь я убежден, что мультииндексные фреймы данных — лучший способ сделать это?
Наш мозг может воспринимать 3 (или даже больше) измерения, так почему кадры данных должны ограничиваться исключительно 2D. Понятно, что это противоречит идее уменьшения размерности, но в некоторых случаях лучше не переусердствовать.
Функциональность мультииндекса в пандах уже давно растет, но у меня все еще есть ощущение, что она не получила достаточного признания.
Позвольте мне затронуть, возможно, основную тревогу новичка в мультииндексации: мультииндексные фреймы данных кажутся громоздкими в обращении. Однако ничто не может быть дальше от реальности. Вот несколько могущественных союзников, которые помогут вам.
Эта функция эффективно позволяет быстро и безболезненно переключаться между уровнями фрейма данных.
Союзник №2. Складывать/разбирать.
Устали от мультииндексации? Перейдите в 2D с любой индексацией, которую вы хотите.
Союзник №3. Другие функции панд.
В последних выпусках многие функции Python имеют аргумент «уровень», который указывает, к какому индексу он должен применяться.
Для демонстрации позвольте мне представить пример 2 функций очистки данных.
def pollution_change_spotter_plants(dfx, threshold): """ Calculate amount of pollutant-years per each plant from 2007 to 2015. Pollutant-year - a relative measure of power plant performance. One pollutant year corresponds to a (one) year when the particular emissions were higher than in 2015. Input: multiindex dataframe created earlier, threshold value for comparison with 2015 - by default 1. Output: regular dataframe """ dfx = dfx[["NOx", "SO2", "Dust"]].copy() dfx = dfx.groupby(level=0).apply(lambda x : x.iloc[-1]/x) df_changed_plants = dfx[dfx < threshold] #selecting plants which polluted more than in 2015 df_changed_plants = df_changed_plants[~df_changed_plants.index.isin(["2015"], level=1)] #dropping 2015 df_changed_plants = len(dfx.groupby(level=1))-df_changed_plants.groupby(level=0).apply(lambda x: x.isna().sum(axis=0)) -1 #number of more polluted years than 2015 return df_changed_plants
И
def pollution_change_spotter_years(dfx, threshold): """ Calculate amount of power plants per year, whose pollution in a given year was more than in 2015. Input: multiindex dataframe created earlier, threshold value for comparison with 2015 - by default 1. Output: regular dataframe """ dfx = dfx[["NOx", "SO2", "Dust"]].copy() dfx = dfx.groupby(level=0).apply(lambda x : x.iloc[-1]/x).replace(0,np.nan) #if result of lambda x >1 -> polluted less than in 2015 df_changed_years = dfx[dfx < threshold] #selecting plants which polluted more than in 2015 df_changed_years = len(dfx.groupby(level=0)) - df_changed_years.groupby(level=1).apply(lambda x: x.isna().sum(axis=0)) -1#number of polluted more df_changed_years.drop(df_changed_years.tail(1).index,inplace=True) return df_changed_years
Самая существенная строка в них:
df_changed_years = len(dfx.groupby(level=n)) - df_changed_years.groupby(level=m).apply(lambda x: x.isna().sum(axis=0)
Единственным отличием является изменение уровня индекса. Тем не менее, это помогает всесторонне анализировать и комбинировать функции на указанной оси. Такие функции могут быть созданы для следующих уровней фрейма данных и обеспечивают значительное улучшение логики и эффективности очистки данных по сравнению с двумерными фреймами данных.
Многоиндексирование – это быстрый и надежный способ манипулирования данными так, как вы их воспринимаете.