#pandas #dataframe
#pandas #фрейм данных
Вопрос:
У меня есть набор данных (около 200 тыс. строк), который выглядит примерно так —
timestamp,cell_id,crnti,enodeb_id,cqi,
1603208435646,3,39062,21519,1,
1603208435946,3,39063,21519,1,
1603208435146,3,39064,21519,2,
1603208435346,3,39064,21519,1,
1603208435546,3,39065,21519,3,
1603208435746,3,39065,21519,1,
1603208435846,3,39062,21519,1,
1603208435946,3,39065,21519,1,
Я хочу суммировать все записи (по crnti) в этом формате —
cell_id,crnti,enodeb_id,cqi,distance_km,session_duration
Здесь продолжительность сеанса вычисляется для каждого crnti с использованием временных меток. Итак, в качестве примера для crnti = 39065 есть 3 записи, поэтому session_duration (дельта 1-й и последней записи) = 1603208435946 — 1603208435546 = 400 мс
и так далее.
cqi — среднее значение для всех значений cqi = среднее значение (3,1,1) = 1,66
Для crnti, которые имеют только одну запись, продолжительность сеанса по умолчанию = 4 сек.
cell_id,crnti,enodeb_id,cqi,session_duration(msec)
3,39065,21519,1.66,400
3,39062,21519,1,4000
Как я могу сделать это в pandas эффективным способом. Я думал о том, чтобы использовать циклы, но это кажется очень неэффективным. Пожалуйста, сообщите.
Ответ №1:
Используйте GroupBy.agg
с именованными агрегатами, затем вычтите максимальные и минимальные значения с DataFrame.pop
помощью for drop columns и установите 4000
, равен ли count 1
by DataFrame.loc
:
df = df.groupby(['cell_id','crnti','enodeb_id']).agg(cqi = ('cqi','mean'),
first = ('timestamp', 'min'),
last = ('timestamp','max'),
count = ('cqi', 'size'))
df['session_duration(msec)'] = df.pop('last').sub(df.pop('first'))
df.loc[df.pop('count').eq(1), 'session_duration(msec)'] = 4000
df = df.reset_index()
print (df)
cell_id crnti enodeb_id cqi session_duration(msec)
0 3 39062 21519 1.000000 200
1 3 39063 21519 1.000000 4000
2 3 39064 21519 1.500000 200
3 3 39065 21519 1.666667 400