Определение изменений в значениях столбцов только в пределах одинаковых значений индекса - PullRequest
0 голосов
/ 03 октября 2018

У меня есть датафрейм, который выглядит следующим образом: https://github.com/thedatasleuth/New-York-Congressional-Districts/blob/master/newyork_total2.csv

Я хотел создать столбец с именем «Flipped», который бы отслеживал изменения в политической партии в пределах район по годам, расположенный в столбце "DOMINANT_PARTY".Так, например, Район 19 переключается с REP на DEM с 2015 по 2016 год. Это то, что я хотел бы отследить как «изменение».Однако я не хотел бы отслеживать изменение между округами - поэтому, например, мне все равно, что было изменение с REP на DEM между Районом 1 и Районом 2. До сих пор я написал следующий код:

for index, row in newyork_total2.iterrows():
    newyork_total2['Flipped'] = newyork_total2['DOMINANT_PARTY'].ne(newyork_total2['DOMINANT_PARTY'].shift().bfill()).astype(int)

Но, как вы можете видеть из моего столбца «Перевернутый», изменения в округах не распознаются.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

вы можете использовать groupby.transform

def find_flip(group):
    return (group.shift(1).notna() & (group != group.shift(1)))

эта функция вычисляет, есть ли переворот в серии

df["FLIPPED"] = df.groupby("DISTRICT")['DOMINANT_PARTY'].transform(find_flip)
0 голосов
/ 03 октября 2018

Вот один подход, использующий lambda с DataFrame.groupby и DataFrame.apply:

f = lambda x: (x.ne(x.shift()) & x.shift().notna()).astype(int)

df['Flipped'] = df.groupby('DISTRICT')['DOMINANT_PARTY'].apply(f).values

Обновление - Объяснение

lambda здесь является сокращением для функции

def flipped(x):
    return x.ne(x.shift()) & x.shift().notna()

Функция принимает Series - в данном случае ['DOMINANT_PARTY'].

Давайте посмотрим на район, где есть«перевернуть», чтобы объяснить (Район 19):

    DISTRICT  Year DOMINANT_PARTY  ...
90        19  2014            REP  ...
91        19  2015            REP  ...
92        19  2016            DEM  ...
93        19  2017            DEM  ...
94        19  2018            DEM  ...

Здесь наша x с примененной функцией - это Серии:

90    REP
91    REP
92    DEM
93    DEM
94    DEM

и x.shift():

90    NaN
91    REP
92    REP
93    DEM
94    DEM

Первое логическое выражение в функции f сравнивает эти ряды с методом Series.ne (не равным), который будет:

90    REP   !=   NaN    True
91    REP   !=   REP    False
92    DEM   !=   REP    True
93    DEM   !=   DEM    False
94    DEM   !=   DEM    False

Обратите внимание, как мыиметь 2 True значений, так как первая строка - 'REP' действительно не равна NaN.Вот почему у нас есть второе логическое выражение для удовлетворения x.shift() НЕ равно NaN (x.shift().notna()).Оператор & является логическим оператором AND, требующим выполнения обоих этих условий.

90    REP   !=   NaN    False
91    REP   !=   REP    False
92    DEM   !=   REP    True
93    DEM   !=   DEM    False
94    DEM   !=   DEM    False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...