#python #python-3.x #pandas #dataframe
Вопрос:
У меня есть фрейм данных:
data = {'process': ['buying','selling','searhicng','repairing', 'preparing', 'selling','buying', 'searching', 'selling','searching'],
'type': ['in_progress','in_progress','end','in_progress', 'in_progress', 'end','in_progress', 'end', 'in_progress','end'],
'country': ['usa','usa', 'usa','ghana', 'ghana','ghana','ghana', 'ghana', 'albania','albania'],
'id': ['022','022','022', '011','011', '011','011', '011', '6','6'],
'duration': [1,1,4,1,2,1,2,3,4,1]
}
df = pd.DataFrame(data, columns = ['process','type','country', 'id', 'duration'])
Мне нужно рассчитать общую продолжительность для строк, где type=in_progress
и до значения type=end
, и создать новый столбец process_line
, содержащий список значений из process
столбца
Кто-нибудь может мне помочь
Выходной кадр данных:
Я попытался пронумеровать каждую строку, а затем выбрать строки с type=in_progress
вычислением общей продолжительности и списком ящиков процесса, но это работает очень медленно
from tqdm import tqdm
k = 0
temp=pd.DataFrame()
res = pd.DataFrame()
for i in tqdm(list(df.drop_duplicates('id').id)):
k=0
temp = df[df.id==i]
for index, row in temp.iterrows():
if row.type=='end':
number = pd.DataFrame([row])
number['nn'] = k
res = pd.concat([res,number])
k =1
else:
number = pd.DataFrame([row])
number['nn'] = k
res = pd.concat([res,number])
Комментарии:
1. Что ты уже пробовал. Каковы ваши идеи?
2. Спасибо за вопрос, я только что добавил его в запрос
Ответ №1:
Что-то вроде этого?
df['type_groups'] = df['type'].shift(1).eq('end').cumsum()
df2 = df[df['type'] != 'end'].groupby('type_groups').agg({'process': list,
'country': 'first',
'id': 'first',
'duration': sum})
Результат
группы типов | процесс | Страна | ID | Продолжительность |
---|---|---|---|---|
0 | [«покупка», «продажа»] | США | 022 | 2 |
1 | [«ремонт», «подготовка»] | гана | 011 | 3 |
2 | [«покупка»] | гана | 011 | 2 |
3 | [«продажа»] | албания | 6 | 4 |
Комментарии:
1. Похоже, что столбцы с «searhicng» не следует учитывать при расчете продолжительности.
2. Это похоже на мой результат, но мы не рассматривали строки с типом=конец при вычислении и создании списка процессов
3. Каково желаемое поведение. Должны ли считаться только строки, которые закончились? Если отсутствует конец, к какому результату вы стремитесь? Не могли бы вы разместить нужную таблицу с парой крайних случаев?
4. Если вам нужно исключить «конечные» строки, мы можем отфильтровать их перед группировкой (см. Мой обновленный ответ). Но, похоже, ты понял это сам!
Ответ №2:
с помощью @fsimonjetz я понял, как я могу это сделать
df['nn'] = df['type'].shift(1).eq('end').cumsum()
in_progress_df = df[df.type=='in_progress'].reset_index()
end_df = df[df.type=='end'].reset_index()
in_progress_grouped = in_progress_df.groupby('nn').agg({'process':list,
'type':'last',
'country':'first',
'id':'first',
'duration':sum,
'nn':'first'})
.rename(columns={'nn':'number'})
res = pd.merge(in_progress_df,end_df , left_on='nn', right_on='nn').drop(labels=['type_x','country_x','id_x','duration_y','index','nn'],axis=1)