Как выполнить повторную выборку / реорганизовать фрейм данных

#python #pandas

#python #pandas

Вопрос:

Это мой фрейм данных.

  df1=pd.DataFrame({'user':['A','A','A','A','B','B','B'], 'status': 
 [1,0,1,0,1,0,1],'bindate':['2019-1-20','','2019-1-27','','2019-1- 
  2','','2019-1-25'],'unbindate':['','2019-1-25','','2019-1-30','','2019- 
 1-20','']})
  

Это выглядит следующим образом

   user   stutas  bindate      unbindate
0  A       1     2019-01-20   Nat
1  A       0     Nat          2019-01-25
2  A       1     2019-01-27   Nat
3  A       0     Nat          2019-01-30
4  B       1     2019-01-02   Nat
5  B       0     Nat          2019-01-20
6  B       1     2019-01-25   Nat
  

Я хочу использовать Pandas для создания нового фрейма данных, который выглядит следующим образом

   user     bindate      unbindate
0  A       2019-01-20   2019-01-25
1  A       2019-01-27   2019-01-30
2  B       2019-01-02   2019-01-20
3  B       2019-01-25   None   
  

Наш сервер фиксирует дату, когда пользователь становится участником, как bindate, и фиксирует дату, когда пользователь создает участника, как unbindate. Если это элемент, статус = 1, иначе статус = 0

Я хочу объединить записи, чтобы создать диапазон дат, чтобы показать пользователя как участника. Обратите внимание, что пользователь A дважды привязывается и развязывается, поэтому A в конечном итоге не является участником. Пользователь B дважды привязывается, один раз развязывается, поэтому в конечном итоге B является участником, поэтому я оставляю unbindate как None. Я пытался использовать .loc для захвата данных, не повезло. Есть ли лучший способ добиться этого? Спасибо.

Ответ №1:

Не эффективно завершать работу, но обрабатывать groupby sorted значение с помощью isnull

 df=df.mask(df=='Nat')
df.groupby('user').apply(lambda x : x.apply(lambda y : sorted(y,key=pd.isnull))).
    dropna(subset=['bindate','unbindate'],thresh=1)
Out[64]: 
  user  stutas     bindate   unbindate
0    A       1  2019-01-20  2019-01-25
1    A       0  2019-01-27  2019-01-30
4    B       1  2019-01-02  2019-01-20
5    B       0  2019-01-25         NaN
  

Комментарии:

1. Спасибо за ваш ответ. Вы использовали вложенное лямбда-выражение, что оно делает? В остальном ваш способ работает, поскольку в реальном мире данные не сортируются чередованием, причем одна строка является датой, а другая — nan.

2. @LiuYu сначала я сгруппирован пользователем, затем для каждой группы я отсортировал значения по ключу, являются ли они нулевыми или нет, если они равны нулю, они были сдвинуты вниз 🙂

3. @LiuYu также, если это решило вашу проблему, хотели бы вы проголосовать за и принять ответ?

4. Просто щелкните стрелку вверх и установите флажок? Я только что сделал. Спасибо. На самом деле меня смущает ваш вложенный лямбда-код. Это действительно работает!

5. Mac такой сложный? лол. Я чувствую то же самое!

Ответ №2:

Если ваш фрейм данных точно такой, как вы показали с чередованием привязки и отмены привязки, shift может быть достаточно:

 df1['unbindate'] = df1.unbindate.shift(-1)
df1 = df1.loc[df1.status != 0].reset_index(drop=True).drop(columns='status')
  

Это дает, как и ожидалось:

   user    bindate  unbindate
0    A  2019-1-20  2019-1-25
1    A  2019-1-27  2019-1-30
2    B  2019-1-02  2019-1-20
3    B  2019-1-25        NaN
  

Комментарии:

1. Спасибо. Правильный путь — сдвиг. исходные данные на самом деле не чередуются. Но я упорядочиваю по user и bindate, теперь они чередуются. Вы просто сделали мой день лучше, спасибо.

2. Подождите, я действительно столкнулся с проблемой. Когда я заказываю фрейм данных. Привязка и развязка не работают как шарм. Все nan движутся к концу. Поэтому я не могу использовать shift. Есть идеи по сортировке данных?