Как изменить значения на основе соседних значений в том же столбце в Pandas - PullRequest
0 голосов
/ 07 июня 2019

Я работаю с набором данных, используя фрейм данных Pandas.Есть два столбца, timestamp и pump_state.Последний - либо 0, либо 1.

enter image description here

Теперь я хочу перебрать столбец pump_state, найти нули, встроенные в них, и изменить их на1, если промежуток времени между ближайшими 1 меньше 5 минут.

Например, строки с 52 по 55. Два 0 смещены на 1.Временная метка 1 перед первым 0 составляет 23:52, а временная метка 1 после последнего 0 - 23,56.Разница во времени этих двух единиц составляет менее 5 минут.Таким образом, 0 нужно изменить на 1.То же самое относится и к 0 в строке 65.

Я мог бы создать словарь между отметкой времени и pump_state, перебрать dict и изменить 0 на 1 на основе логики.Затем обновите фрейм данных новым словарем.Но есть ли лучший способ (или более пандский способ) сделать это?

1 Ответ

0 голосов
/ 07 июня 2019

Рассмотрим следующий подход (следуйте комментариям):

import numpy as np
import pandas as pd

# create sample data
NUM = 30
df = pd.DataFrame({
    'timestamp': pd.date_range(start='5/29/2019 00:00:00',
                               periods=NUM, freq='1min'),
    'pump_state': [1] * NUM})
df.loc[5:8, 'pump_state'] = 0  # 4 zeros - 4 minutes < 5 minutes
df.loc[15:25, 'pump_state'] = 0  # 10 zeros - 10 minutes > 5 minutes

# search for rows where 0 switches to 1 and vice versa
df['diff'] = df['pump_state'].diff()
df['diff_1'] = np.where(df['diff'] == 1, 1, -1)
df['diff_-1'] = np.where(df['diff'] == -1, 1, -2)

# merge all found swithces (like join in SQL)
df_support = pd.merge(
    df, df, how='inner',
    left_on='diff_1', right_on='diff_-1')[['timestamp_x', 'timestamp_y']]

# apply timing conditions to all pairs of switches
df_support = df_support[
    # less than 5 minutes
    (df_support['timestamp_x'] - df_support['timestamp_y'] < pd.Timedelta(minutes=5)) &
    # greater than zero
    (df_support['timestamp_x'] - df_support['timestamp_y'] > pd.Timedelta(0))]

# replace 0s with 1s where it is appropriate
for idx, row in df_support.iterrows():
    df.loc[(df['timestamp'] >= row['timestamp_y']) &
           (df['timestamp'] <= row['timestamp_x']),
           'pump_state'] = 1

df.drop(columns=['diff', 'diff_1', 'diff_-1'], inplace=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...