Элегантный способ замены нескольких столбцов условным

#pandas #conditional-statements

Вопрос:

В настоящее время я использую следующую строку для замены значения столбцов, если выполняется определенное условие.

 df.loc[df['event'] == 1, 'pre'] = 0
df.loc[df['event'] == 1, 'post'] = 1

df.loc[df['event'] == 2, 'pre'] = 1
df.loc[df['event'] == 2, 'post'] = 0

df.loc[df['event'] == 4, 'pre'] = 1
df.loc[df['event'] == 4, 'post'] = 0
 

Но это не масштабируемо.

Могу ли я узнать более эффективные способы сделать это?

 import numpy as np
import pandas as pd
nfreq=500
arr=np.array([[11850,0,1],
[12310,0,3],
[13924,0,4],
[16690,0,1],
[17082,0,3],
[18746,0,4],
[21956,0,2],
[22324,0,3],
[23694,0,4],
[25382,0,1],
[25776,0,3],
[28592,0,4],
[31676,0,2],
[32028,0,3],
[33498,0,4]])
trange = np.where(arr == 3)[0]
val=np.array([arr[trange, 0],arr[trange, 2],
          (arr[trange, 0]-arr[trange-1, 0])/nfreq,
          (arr[trange 1, 0]-arr[trange, 0])/nfreq]).T


trange= np.where(arr[:,2] != 3)[0]
val_oth=np.array([arr[trange, 0],arr[trange, 2],arr[trange, 2],arr[trange, 2]]).T
val_oth[:,2]=1
val_oth[:,-1]=1
df = pd.DataFrame(np.vstack((val,val_oth)),columns=['timepoint','event','pre','post'])
df.loc[df['event'] == 1, 'pre'] = 0
df.loc[df['event'] == 1, 'post'] = 1

df.loc[df['event'] == 2, 'pre'] = 1
df.loc[df['event'] == 2, 'post'] = 0

df.loc[df['event'] == 4, 'pre'] = 1
df.loc[df['event'] == 4, 'post'] = 0
df.sort_values(by='timepoint', ascending=True,inplace=True)
df.reset_index(drop=True,inplace=True)
 

Комментарии:

1. Для «событие = 2 и 4» вы устанавливаете post дважды с разными значениями. Опечатка?

2. Спасибо за орлиный взгляд

Ответ №1:

Вы можете установить оба столбца одновременно и объединить выбранные при назначении одних и тех же значений

 df.loc[df.event==1, ['pre','post']] = [0,1]
df.loc[df.event.isin([2,4]), ['pre','post']] = [1,0]
 

Если столбец event вычисляется, я бы предложил преобразовать его в int, чтобы избежать ошибок с плавающей запятой

 df['event'] = df.event.astype('int')