Создание фиктивных переменных для последнего выбора - Pandas - PullRequest
1 голос
/ 24 сентября 2019

У меня есть этот фрейм данных:

ID  Date        X   choice
A   07/16/2019  .   123
A   07/17/2019  .   789
A   07/18/2019  .   0
A   07/19/2019  .   456
B   07/16/2019  .   0
B   07/16/2019  .   789
B   07/17/2019  .   0
B   07/18/2019  .   123

Я хочу создать фиктивные переменные, которые будут указывать, была ли конкретная альтернатива из множества альтернатив (123, 456, 789) последней.

Примечания:

  • Это должно быть сделано для каждого удостоверения личности отдельно.
  • Значение 0 означает, что выбора нет, поэтому необходимо заполнить предыдущий выбор (перед значением 0).

Ожидаемый результат:

ID  Date        X   choice  123_L   456_L   789_L
A   07/16/2019  .   123     0       0       0
A   07/17/2019  .   789     1       0       0
A   07/18/2019  .   0       0       0       1
A   07/19/2019  .   456     0       0       1
B   07/16/2019  .   0       0       0       0
B   07/16/2019  .   789     0       0       0
B   07/17/2019  .   0       0       0       1
B   07/18/2019  .   123     0       0       1

Ответы [ 3 ]

2 голосов
/ 24 сентября 2019

Вы хотите get_dummies:

new_df = (pd.get_dummies(df.choice.where(df.choice.ne(0))
                           .groupby(df['ID']).ffill()
                           .fillna(0).astype(int))
            .groupby(df['ID'])
            .shift(fill_value=0)
            .add_suffix('_L')
         )

pd.concat((df, new_df), axis=1)

Вывод:

  ID        Date  X  choice  0_L  123_L  456_L  789_L
0  A  07/16/2019  .     123    0      0      0      0
1  A  07/17/2019  .     789    0      1      0      0
2  A  07/18/2019  .       0    0      0      0      1
3  A  07/19/2019  .     456    0      0      0      1
4  B  07/16/2019  .       0    0      0      0      0
5  B  07/16/2019  .     789    1      0      0      0
6  B  07/17/2019  .       0    0      0      0      1
7  B  07/18/2019  .     123    0      0      0      1
1 голос
/ 26 сентября 2019

Вы можете сначала обработать choice для замены 0 на пропущенные значения и по группам ID сначала сдвинуть и затем заполнить пропущенные значения вперед:

s = (df['choice'].mask(df['choice'].eq(0))
                 .groupby(df['ID'])
                 .apply(lambda x: x.shift().ffill()))

Затем использовать get_dummies из Series с и добавьте DataFrame.reindex для всех возможных строк из списка или из исходных столбцов без 0 и переименуйте столбцы с DataFrame.add_suffix:

#possible values in list
#vals = [123, 456, 789]

#extract all sorted values without 0
vals = df['choice'].unique()
vals = np.sort(vals[vals != 0])
df = (df.join(pd.get_dummies(s)
                .reindex(columns=vals, fill_value=0)
                .add_suffix('_L')))

print (df)
  ID        Date  X  choice  123_L  456_L  789_L
0  A  07/16/2019  .     123      0      0      0
1  A  07/17/2019  .     789      1      0      0
2  A  07/18/2019  .       0      0      0      1
3  A  07/19/2019  .     456      0      0      1
4  B  07/16/2019  .       0      0      0      0
5  B  07/16/2019  .     789      0      0      0
6  B  07/17/2019  .       0      0      0      1
7  B  07/18/2019  .     123      0      0      1
0 голосов
/ 24 сентября 2019

шагов - создать столбец, который заменяет 0 на последний выбор, используя ffill - с помощью бесшумного широковещания сравнить уникальные варианты со смещенным последним выбором, чтобы получить фиктивные данные - создать фиктивные данные из фрейма данных и объединить их в df

Редактировать
- исправлен код без учета идентификаторов - также добавлена ​​строка 5 для его проверки

import numpy as np
import pandas as pd

ls = [("A", "07/16/2019 ", 123),
("A", "07/17/2019 ", 789),
("A", "07/18/2019 ", 0),
("A", "07/19/2019 ", 456),
("B", "07/16/2019 ", 789),
("B", "07/18/2019 ", 123),
("B", "07/17/2019 ", 0),
("B", "07/18/2019 ", 123),]

df = pd.DataFrame(ls, columns=["id", "date", "choice"])

df = df.sort_values("id")
prev_choice = df["choice"].mask(df["choice"]==0, np.nan).ffill().shift()

prev_choice[df["id"]!=df["id"].shift()] = 0

unique_choices = np.delete(np.unique(df["choice"]), 0)

last_choice = np.zeros((len(df), len(unique_choices)))

last_choice = np.equal(unique_choices[np.newaxis,:], prev_choice                       
                       .values[:, np.newaxis])

dummy_df = pd.DataFrame(last_choice, columns = [f"{choice}_L" for choice in unique_choices])

pd.concat([df, dummy_df], axis=1)


Результат

    id  date    choice  123_L   456_L   789_L
0   A   07/16/2019  123 False   False   False
1   A   07/17/2019  789 True    False   False
2   A   07/18/2019  0   False   False   True
3   A   07/19/2019  456 False   False   True
4   B   07/16/2019  789 False   False   False
5   B   07/18/2019  123 False   False   True
6   B   07/17/2019  0   True    False   False
7   B   07/18/2019  123 True    False   False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...