#python #pandas #dataframe #data-science
Вопрос:
Предположим, у меня есть фрейм данных Pandas, подобный следующему:
ID update_time cap date diff
A 05/05/21 1:45 136 05/05/21 136
A 05/05/21 1:50 0 05/05/21 -136
A 05/05/21 2:10 1 05/05/21 1
A 05/05/21 2:15 0 05/05/21 -1
A 05/05/21 3:35 1 05/05/21 1
A 05/05/21 3:40 0 05/05/21 -1
A 05/05/21 14:40 158 06/05/21 158
A 05/05/21 14:45 0 06/05/21 -158
A 05/05/21 15:10 1 06/05/21 1
A 07/05/21 9:49 0 07/05/21 -1
B 05/05/21 1:10 500 05/05/21 500
B 05/05/21 1:15 63 05/05/21 -437
B 05/05/21 1:20 0 05/05/21 -63
B 05/05/21 1:35 8 05/05/21 8
B 05/05/21 1:40 0 05/05/21 -8
B 05/05/21 1:45 3 05/05/21 3
B 05/05/21 1:50 0 05/05/21 -3
B 05/05/21 14:35 255 06/05/21 255
B 05/05/21 14:40 0 06/05/21 -255
Я хочу отбросить все cap
значения, которые появляются после первого падения, до 0 в пределах каждого идентификатора и даты. Есть какие-нибудь указания на то, как я могу этого достичь? Я приложил ожидаемый результат ниже.
ID update_time cap date diff
A 05/05/21 1:45 136 05/05/21 136
A 05/05/21 1:50 0 05/05/21 -136
A 05/05/21 14:40 158 06/05/21 158
A 05/05/21 14:45 0 06/05/21 -158
B 05/05/21 1:10 500 05/05/21 500
B 05/05/21 1:15 63 05/05/21 -437
B 05/05/21 1:20 0 05/05/21 -63
B 05/05/21 14:35 255 06/05/21 255
B 05/05/21 14:40 0 06/05/21 -255
Любые указатели будут оценены по достоинству!
Комментарии:
1. Что означает «после того, как они изначально упадут до 0»? Как получилось, что строка «A, 158» существует, если мы исключаем все после 0, почему бы не рассмотреть строки «A, 1»?
2. A, 158 выбрано, так как значение в столбце «дата» изменяется.
3. @thinrhino это важная деталь, которую я бы рекомендовал вам добавить в свой вопрос!
Ответ №1:
Сначала вам нужно выполнить groupby
ID
операцию «и date
«, так как вы хотите "all rows before a drop to 0 occurs in caps"
для каждой уникальной комбинации идентификатора и даты. Затем мы применим пользовательскую функцию, которая выбирает все строки до появления первого нуля. Функция учитывает граничный случай, когда «падение до 0» не может произойти для даты идентификатора, которая происходит только один раз.
Обратите внимание, что я использовал только соответствующую часть вашего фрейма данных.
import numpy as np
import pandas as pd
## recreate the relevant portion of your DataFrame
df = pd.DataFrame({
'ID':['A']*10 ['B']*9,
'cap':[136,0,1,0,1,0,158,0,1,0,500,63,0,8,0,3,0,255,0],
'date':['05/05/21']*6 ['06/05/21']*3 ['07/05/21'] ['05/05/21']*7 ['06/05/21']*2
})
## get the caps values before the first occurrence of a zero
def get_caps_before_zero(df_column):
## for an ID-cap groupby of length 1, no "drop" to zero can occur, so return an empty DataFrame
if len(df_column) == 1:
return df_column.iloc[0:0]
else:
idx_first_zero = np.where(df_column == 0)[0].min() 1
return df_column.iloc[:idx_first_zero]
df_subset = (df.groupby(['ID','date'])
.apply(lambda x: get_caps_before_zero(x['cap']))
.reset_index()
.drop(columns='level_2')
)
Выход:
>>> df_subset
ID date cap
0 A 05/05/21 136
1 A 05/05/21 0
2 A 06/05/21 158
3 A 06/05/21 0
4 B 05/05/21 500
5 B 05/05/21 63
6 B 05/05/21 0
7 B 06/05/21 255
8 B 06/05/21 0
Комментарии:
1. Спасибо вам за решение. Узнал несколько новых вещей о пандах.
2. Нет проблем, рад, что мое решение оказалось полезным!