Создайте новый столбец между двумя элементами и между() python

#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. Вам нужно изменить их на списки (чтобы мы знали, какой из них первый, а какой последний). Наборы не заказываются.