Вычислить разницу между двумя столбцами и двумя последующими строками для другой группы - PullRequest
1 голос
/ 13 июля 2020

Существуют ли какие-либо векторные операции для улучшения времени выполнения?

Я не нашел другого способа, кроме циклов.

Пример DataFrame:

df = pd.DataFrame({'ID': ['1', '1','1','2','2','2'], 
                       'start_date': ['01-Jan', '05-Jan', '08-Jan', '05-Jan','06-Jan', '10-Jan'],
                       'start_value': [12, 15, 1, 3, 2, 6],
                       'end_value': [20, 17, 6,19,13.5,9]})

  ID start_date  start_value  end_value
0  1     01-Jan           12       20.0
1  1     05-Jan           15       17.0
2  1     08-Jan            1        6.0
3  2     05-Jan            3       19.0
4  2     06-Jan            2       13.5
5  2     10-Jan            6        9.0

Я пробовал:

import pandas as pd

df_original # contains data


data_frame_diff= pd.DataFrame()

for ID in df_original ['ID'].unique():
    tmp_frame = df_original .loc[df_original ['ID']==ID]
    tmp_start_value = 0

    for label, row in tmp_frame.iterrows():
        last_delta = tmp_start_value - row['value']
        tmp_start_value = row['end_value']

        row['last_delta'] = last_delta
        data_frame_diff= data_frame_diff.append(row,True)

Ожидаемый результат:

df = pd.DataFrame({'ID': ['1', '1','1','2','2','2'], 
                   'start_date': ['01-Jan', '05-Jan', '08-Jan', '05-Jan', '06-Jan', 
                                 '10-Jan'],
                   'last_delta': [0, 5, 16, 0, 17, 7.5]})

  ID start_date  last_delta
0  1     01-Jan         0.0
1  1     05-Jan         5.0
2  1     08-Jan        16.0
3  2     05-Jan         0.0
4  2     06-Jan        17.0
5  2     10-Jan         7.5

Я хочу рассчитать дельта между start_value и end_value метки времени и следующей меткой времени после для каждого пользователя ID.

Есть ли способ улучшить время выполнения этого кода?

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Используйте DataFrame.groupby для ID и shift столбца end_value, затем используйте Series.sub, чтобы вычесть его из start_value, наконец, используйте Series.fillna и назначьте этот новый столбец s фрейму данных, используя DataFrame.assign:

s = df.groupby('ID')['end_value'].shift().sub(df['start_value']).fillna(0)
df1 = df[['ID', 'start_date']].assign(last_delta=s)

Результат:

print(df1)

  ID start_date  last_delta
0  1     01-Jan         0.0
1  1     05-Jan         5.0
2  1     08-Jan        16.0
3  2     05-Jan         0.0
4  2     06-Jan        17.0
5  2     10-Jan         7.5
0 голосов
/ 13 июля 2020

Из вашего описания немного сложно понять, что вам нужно, но вы можете найти это полезным:

import pandas as pd

df = (pd.DataFrame({'t1': pd.date_range(start="2020-01-01", end="2020-01-02", freq="H"),
                   })
       .reset_index().rename(columns={'index': 'ID'})
      )

df['t2'] = df['t1']+pd.Timedelta(value=10, unit="H")                 
df['delta_t1_t2'] = df['t2']-df['t1']
df['delta_to_previous_t1'] = df['t1'] - df['t1'].shift()

print(df)

Это приводит к

    ID                  t1                  t2 delta_t1_t2 delta_to_previous_t1
0    0 2020-01-01 00:00:00 2020-01-01 10:00:00    10:00:00                  NaT
1    1 2020-01-01 01:00:00 2020-01-01 11:00:00    10:00:00             01:00:00
2    2 2020-01-01 02:00:00 2020-01-01 12:00:00    10:00:00             01:00:00
3    3 2020-01-01 03:00:00 2020-01-01 13:00:00    10:00:00             01:00:00
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...