Как найти скорость изменения по последовательным строкам, используя столбцы времени и данных после группировки по другому столбцу, используя панды? - PullRequest
0 голосов
/ 01 октября 2018

У меня есть пандас DataFrame в форме:

df

ID_col time_in_hours data_col
  1        62.5         4
  1        40           3
  1        20           3
  2        30           1
  2        20           5
  3        50           6

Что я хочу сделать, это найти скорость изменения data_col с использованием столбца time_in_hours.В частности,

rate_of_change = (data_col[i+1] - data_col[i]) / abs(time_in_hours[ i +1] - time_in_hours[i])

Где i - это заданная строка, а rate_of_change рассчитывается отдельно для разных идентификаторов

Фактически, я хочу новуюDataFrame формы:

new_df

ID_col time_in_hours data_col  rate_of_change
  1        62.5         4          NaN
  1        40           3         -0.044
  1        20           3          0
  2        30           1          NaN
  2        20           5          0.4
  3        50           6          NaN

Как мне это сделать?

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Вы можете использовать pandas.diff:

df.groupby('ID_col').apply(
   lambda x: x['data_col'].diff() / x['time_in_hours'].diff().abs())

ID_col   
1       0         NaN
        1   -0.044444
        2    0.000000
2       3         NaN
        4    0.400000
3       5         NaN
dtype: float64
0 голосов
/ 01 октября 2018

Вы действительно можете обойти groupby + apply, учитывая, как ваш DataFrame сортируется.В этом случае вы можете просто проверить, совпадает ли ID_col со смещенной строкой.

Поэтому рассчитайте скорость изменения для всего, а затем присваивайте значения обратно только в том случае, если они находятся в группе.

import numpy as np

mask = df.ID_col == df.ID_col.shift(1)
roc = (df.data_col - df.data_col.shift(1))/np.abs(df.time_in_hours - df.time_in_hours.shift(1))

df.loc[mask, 'rate_of_change'] = roc[mask] 

Вывод:

   ID_col  time_in_hours  data_col  rate_of_change
0       1           62.5         4             NaN
1       1           40.0         3       -0.044444
2       1           20.0         3        0.000000
3       2           30.0         1             NaN
4       2           20.0         5        0.400000
5       3           50.0         6             NaN
0 голосов
/ 01 октября 2018

Вы можете использовать groupby :

s = df.groupby('ID_col').apply(lambda dft: dft['data_col'].diff() / dft['time_in_hours'].diff().abs())
s.index = s.index.droplevel()
s

возвращает

0         NaN
1   -0.044444
2    0.000000
3         NaN
4    0.400000
5         NaN
dtype: float64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...