Более быстрые методы, чем iterrows с условиями (предшественник и преемник каждого ряда) - PullRequest
0 голосов
/ 11 сентября 2018

У меня проблема в том, что код снизу очень медленный.Я давно не работал с Python и Pandas, поэтому не знаю точно, с чего начать.

Я хочу определить предшественника и преемника каждой строки.

В настоящее время я выполняю итерацию по каждой строке и выводю строки, соответствующие моим условиям.Из этих серий я определяю максимум и минимум один раз.

У меня есть следующая запись:

index   Case    Button      Start                       rowNow
0       x       a           2017-12-06 10:17:43.227     0
1       x       b           2017-12-06 10:17:44.876     1
2       x       c           2017-12-06 10:17:45.719     2
3       y       a           2017-12-06 15:28:57.500     3
4       y       e           2017-12-06 15:29:19.079     4

И я хочу ее получить:

index   Case    Button      Start                       rowNow  prevNum nextNum
0       x       a           2017-12-06 10:17:43.227     0       NaN     1
1       x       b           2017-12-06 10:17:44.876     1       0       2
2       x       c           2017-12-06 10:17:45.719     2       1       NaN
3       y       a           2017-12-06 15:28:57.500     3       NaN     4
4       y       e           2017-12-06 15:29:19.079     4       3       NaN

Можеткто-нибудь дать мне несколько советов о том, как оптимизировать скорость этого кода?Можно ли вообще использовать здесь векторизацию?

for index, row in df.iterrows():

    x = df[(df['Case'] == row['Case']) & (df['rowNow'] < row['rowNow']) & (row['Start'] >= df['Start'])]
    df.loc[index,'prevNum'] = x['rowNow'].max()
    y = df[(df['Case'] == row['Case']) & (df['rowNow'] > row['rowNow']) & (row['Start'] <= df['Start'])]    
    df.loc[index,'nextNum'] = y['rowNow'].min()

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Попробуйте:

df['prevNum'] = df.groupby('Case').apply(lambda x:x[['rowNow']].shift(1))
df['nextNum'] = df.groupby('Case').apply(lambda x:x[['rowNow']].shift(-1))
0 голосов
/ 11 сентября 2018

Попробуйте:

df['Start']=pd.to_datetime(df['Start'])
df['prevNum']=df['rowNow'].shift()
df['nextNum']=df['rowNow'].shift(-1)
df.loc[df['Start'].dt.hour!=df['Start'].shift().dt.hour,'prevNum']=pd.np.nan
df.loc[df['Start'].dt.hour!=df['Start'].shift(-1).dt.hour,'nextNum']=pd.np.nan
print(df)

Если столбец start не является форматом даты и времени, выполните:

df['Start']=pd.to_datetime(df['Start'])

прежде всего

Выход:

  index Case      Button                   Start  rowNow  prevNum  nextNum
0     x    a  2017-12-06 2018-09-11 10:17:43.227       0      NaN      1.0
1     x    b  2017-12-06 2018-09-11 10:17:44.876       1      0.0      2.0
2     x    c  2017-12-06 2018-09-11 10:17:45.719       2      1.0      NaN
3     y    a  2017-12-06 2018-09-11 15:28:57.500       3      NaN      4.0
4     y    e  2017-12-06 2018-09-11 15:29:19.079       4      3.0      NaN
...