петли панд на элементы - PullRequest
0 голосов
/ 03 июля 2018

Я хотел бы вычислить дельта-время в кадре данных (с некоторым условием), поэтому я пишу цикл:

for i in range(1,len(df.index)):
    if df.type[i] == df.type[i-1]:
        df.delta[i]=df.time[i]-df.time[i-1]
    else:
        df.delta[i]= ''

но кажется не очень оптимизированным, потому что он очень длинный, и я получаю SettingWithCopyWarning (чего я не понимаю). Каков наилучший способ сделать такое вычисление?

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Вы должны использовать векторизованный подход. Например, вы можете использовать numpy.where с pd.Series.shift и pd.Series.diff:

df['C_id'] = np.where(df['type'] == df['type'].shift(), df['time'].diff(), np.nan)

Примечание. Я настоятельно рекомендую вам , а не использовать пустую строку '' в качестве альтернативного значения, так как это заставит вашу серию иметь object dtype вместо float.

0 голосов
/ 03 июля 2018

Я бы использовал .shift () для этого. Создает новый столбец со значениями, сдвинутыми на 1. Поэтому, если у нас нет условий, вам понадобится просто df["time"] - df["time"].shift(), но если вы хотите добавить условие, where поможет. Итак, вот решение в одну строку

(df["time"] - df["time"].shift()).where(df["type"] == df["type"].shift(), "")

Или, как предлагается в другом ответе, вы можете использовать diff

df["time"].diff().where(df["type"] == df["type"].shift(), "")
0 голосов
/ 03 июля 2018

Мой подход будет использовать pandas.apply ()

type_prev = ''
time_prev = 0

def lambda_func(row):
    global type_prev
    global time_prev
    if row['type'] == time_prev:
        time_diff = row['time'] - time_prev
    else:
        time_diff = ''
    time_prev = row['time']
    type_prev = row['type']
    return time_diff

df['delta'] = df.apply(lambda_func)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...