#python #pandas #dataframe
Вопрос:
У меня есть фрейм данных data_set
и две важные информации в списке
cond_list = [{'LQ','DA'},{'HJ','OP'}]
.
Сообщите всю информацию между двумя значениями LQ and DA
ИЛИ HJ and OP
в новом столбце «Другой проход», и какое условие в тот же день и тот же идентификатор.
Пример:
Пусть i, j соответствуют рангу LQ и DA соответственно. i
- Идентификатор 1552, дата 1/4/2020, у нас есть информация[‘LQ’], соответствующая рангу = 1, и информация[‘DA’], соответствующая рангу = 4 — gt; Поэтому вся информация «Еще один проход» включает [LA, BA], потому что Ранг DA gt;lt; Ранг LA, Ранг BA
- Идентификатор 1552, дата 5/4/2020, у нас есть информация[‘LQ’], соответствующая рангу = 3, и информация[‘DA’], соответствующая рангу = 7 — gt; Поэтому вся информация «Еще один проход» включает [VT,AN,VB], потому что Ранг DA gt;lt; Ранг VT, Ранг AN, Ранг VB
- Идентификатор 1697, дата 15/4/2020, у нас есть информация[‘LQ’], соответствующая рангу = 1, и информация[‘DA’], соответствующая рангу = 4, но между этими двумя точками нет информации, поэтому «Другой проход» пуст
Ввод:
ID | Дата | Ранг | Информация | Horaire | Тип | Примечание |
---|---|---|---|---|---|---|
1552 | 1/4/2020 | 1 | LQ | 10:00 | D | LVM |
1552 | 1/4/2020 | 1 | LQ | 10:10 | A | LVM |
1552 | 1/4/2020 | 2 | LA | 10:12 | P | |
1552 | 1/4/2020 | 3 | ба | 10:15 | P | |
1552 | 1/4/2020 | 4 | DA | 10:25 | A | LVD |
1552 | 5/4/2020 | 1 | dt | 11:30 | D | |
1552 | 5/4/2020 | 2 | gr | 11:33 | P | |
1552 | 5/4/2020 | 3 | LQ | 11:35 | D | LDT |
1552 | 5/4/2020 | 3 | LQ | 11:38 | A | |
1552 | 5/4/2020 | 4 | vt | 11:40 | P | |
1552 | 5/4/2020 | 5 | ОДИН | 11:43 | P | |
1552 | 5/4/2020 | 6 | гл. | 11:46 | P | |
1552 | 5/4/2020 | 7 | DA | 11:55 | A | LDF |
1552 | 5/4/2020 | 7 | DA | 11:59 | D | |
1552 | 5/4/2020 | 8 | около | 12:15 | A | |
1697 | 15/4/2020 | 1 | hj | 10:00 | D | LVM |
1697 | 15/4/2020 | 4 | OP | 11:00 | A | LVM |
i filtered a table of values containing only two condition elements:
mask = df.groupby(['ID', 'Date'])['Info'].agg(set).apply(lambda x: any([y.issubset(x) for y in cond_list])) data_set = df.set_index(['ID', 'Date']).loc[mask].reset_index() dt_final = data_set.loc[data_set['Info'].isin(cond.values.ravel())]
Я получаю новый фрейм данных «dt_final»:
ID | Дата | Ранг | Информация | Horaire | Тип | Примечание |
---|---|---|---|---|---|---|
1552 | 1/4/2020 | 1 | LQ | 10:00 | D | LVM |
1552 | 1/4/2020 | 1 | LQ | 10:10 | A | LVM |
1552 | 1/4/2020 | 4 | DA | 10:25 | A | LVD |
1552 | 5/4/2020 | 3 | LQ | 11:35 | D | LDT |
1552 | 5/4/2020 | 3 | LQ | 11:38 | A | |
1552 | 5/4/2020 | 7 | DA | 11:55 | A | LDF |
1552 | 5/4/2020 | 7 | DA | 11:59 | D | |
1697 | 15/4/2020 | 1 | hj | 10:00 | D | LVM |
1697 | 15/4/2020 | 4 | OP | 11:00 | A | LVM |
Я говорю, что массив значений «Ранг»:
cd = dt_final.groupby(["ID", "Date"])["Rank"].agg(list).tolist()
я фильтрую значения между:
for i in cd: pr['Another Pass'] = data_set.loc[data_set.Rank.between(i[0],i[-1])].groupby(['ID', 'Date ']).agg({'Info':list})
Хотя он объявляет всю информацию по одной и той же дате и одному и тому же идентификатору, а не по требуемым значениям между двумя точками в списке условий cond_list и, например 🙁
Комментарии:
1. Могут ли один и тот же идентификатор и дата иметь как LQ, DA, так и HJ, OP?
2. его данные очень велики, и я не могу проверить их все, но я думаю, что не существует случая, когда оба условия поставки в один день. Так что я думаю, что да.
Ответ №1:
Поскольку один и тот же идентификатор и дата не могут иметь оба набора значений, вы можете попробовать:
cond_list = [['LQ','DA'],['HJ','OP']] firsts = [s[0] for s in cond_list] lasts = [s[-1] for s in cond_list] another_pass= df.groupby(["ID", "Date"]) .apply(lambda x: x[x["Rank"].between(x[x["Info"].isin(firsts)]["Rank"].min(), x[x["Info"].isin(lasts)]["Rank"].max(), inclusive="neither")]["Info"].tolist()) .rename("Another Pass") gt;gt;gt; output ID Date 1552 1/4/2020 [LA, BA] 5/4/2020 [VT, AN, VB] 1697 15/4/2020 []
Если вы хотите объединить это обратно в исходный кадр данных, чтобы создать новый столбец:
output = df.merge(another_pass, left_on = ["ID", "Date"], right_index=True) gt;gt;gt; output ID Date Rank Info Horaire Type Note Another Pass 0 1552 1/4/2020 1 LQ 10:00 D LVM [LA, BA] 1 1552 1/4/2020 1 LQ 10:10 A LVM [LA, BA] 2 1552 1/4/2020 2 LA 10:12 P NaN [LA, BA] 3 1552 1/4/2020 3 BA 10:15 P NaN [LA, BA] 4 1552 1/4/2020 4 DA 10:25 A LVD [LA, BA] 5 1552 5/4/2020 1 DT 11:30 D NaN [VT, AN, VB] 6 1552 5/4/2020 2 GR 11:33 P NaN [VT, AN, VB] 7 1552 5/4/2020 3 LQ 11:35 D LDT [VT, AN, VB] 8 1552 5/4/2020 3 LQ 11:38 A NaN [VT, AN, VB] 9 1552 5/4/2020 4 VT 11:40 P NaN [VT, AN, VB] 10 1552 5/4/2020 5 AN 11:43 P NaN [VT, AN, VB] 11 1552 5/4/2020 6 VB 11:46 P NaN [VT, AN, VB] 12 1552 5/4/2020 7 DA 11:55 A LDF [VT, AN, VB] 13 1552 5/4/2020 7 DA 11:59 D NaN [VT, AN, VB] 14 1552 5/4/2020 8 AT 12:15 A NaN [VT, AN, VB] 15 1697 15/4/2020 1 HJ 10:00 D LVM [] 16 1697 15/4/2020 4 OP 11:00 A LVM []
Редактировать:
Для требуемых строк из выходных данных вы можете сделать:
gt;gt;gt; output[((output["Info"].isin(["LQ", "HJ"])) amp; (output["Type"]=="D")) | ((output["Info"].isin(["DA", "OP"])) amp; (output["Type"]=="A"))] ID Date Rank Info Horaire Type Note Another Pass 0 1552 1/4/2020 1 LQ 10:00 D LVM [LA, BA] 4 1552 1/4/2020 4 DA 10:25 A LVD [LA, BA] 7 1552 5/4/2020 3 LQ 11:35 D LDT [VT, AN, VB] 12 1552 5/4/2020 7 DA 11:55 A LDF [VT, AN, VB] 15 1697 15/4/2020 1 HJ 10:00 D LVM [] 16 1697 15/4/2020 4 OP 11:00 A LVM []
Комментарии:
1. Есть ли способ использовать его непосредственно из значения cond_list?
2. @Poohlikepooh — Отредактировал его по мере необходимости.
3. @Poohlikepooh — Смотри правку! Если у вас есть еще какие-либо дополнительные вопросы, я бы предложил опубликовать новый пост, так как на этот текущий вопрос был дан ответ!
4. Для первых и последних он объявляет, что «объект set’ не подлежит подписке»: (((((
5. Вам нужно изменить их на списки (чтобы мы знали, какой из них первый, а какой последний). Наборы не заказываются.