#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. Есть идеи по сортировке данных?