Панды: сдвиг после N струн - PullRequest
0 голосов
/ 29 июня 2018

у меня есть датафрейм

        atm_id     dNDCSessionTime  sCardNumber  nTrRequestCount  
152865       0 2017-01-14 07:56:17            1                1   
153052       0 2017-01-14 08:01:13            1                1   
153053       0 2017-01-14 08:02:19            1                1   
153054       0 2017-01-14 08:03:41            1                1   
152804       0 2017-01-14 08:04:37            1                1   
152805       0 2017-01-14 08:05:24            1                1   
152806       1 2017-01-14 08:06:08            1                1   
152807       1 2017-01-14 08:07:15            1                1   
152808       1 2017-01-14 08:08:08            1                1   
152866       1 2017-01-14 08:08:50            1                1   

Мне нужно добавить новые столбцы, что означает период. (Для каждого atm_id каждые 3 транзакции (строки в кадре данных))

Желаемый выход

            atm_id     dNDCSessionTime  sCardNumber  nTrRequestCount period
152865       0 2017-01-14 07:56:17            1                1      1
153052       0 2017-01-14 08:01:13            1                1      1
153053       0 2017-01-14 08:02:19            1                1      1
153054       0 2017-01-14 08:03:41            1                1      2
152804       0 2017-01-14 08:04:37            1                1      2
152805       0 2017-01-14 08:05:24            1                1      2
152806       1 2017-01-14 08:06:08            1                1      3
152807       1 2017-01-14 08:07:15            1                1      3
152808       1 2017-01-14 08:08:08            1                1      3
152866       1 2017-01-14 08:08:50            1                1      4

Я пытаюсь сделать это с

df['period'] = df.sort_values(['atm_id', 'dNDCSessionTime']).groupby('atm_id').shift(500)

Но у меня ошибка.

1 Ответ

0 голосов
/ 29 июня 2018

Если, как в вашем примере, число строк в 'atm_id' кратно 3, то вы можете использовать iloc[::3] для выбора каждых 3 строк.

# initiate the column
df['Period'] = None
# select every three rows and assign 1 there in the column Period
df['Period'].iloc[::3] = 1
# use cumsum, ffill and astype to populate an incremental value every 3 rows
df['Period'] = df['Period'].cumsum().ffill().astype(int)

Теперь я предполагаю, что вы не всегда будете иметь количество строк, кратное 3, в пределах atm_id, поэтому вы можете перейти к groupby и apply. Я добавил строку к вашему вводу с atm_id = 2, чтобы сделать точку. Если вы делаете:

print (df.groupby('atm_id').apply(lambda x: x.iloc[::3]))

               atm_id     dNDCSessionTime  sCardNumber  nTrRequestCount Period
atm_id                                                                        
0      152865       0 2017-01-14 07:56:17            1                1   None
       153054       0 2017-01-14 08:03:41            1                1   None
1      152806       1 2017-01-14 08:06:08            1                1   None
       152866       1 2017-01-14 08:08:50            1                1   None
2      152887       2 2017-01-12 07:56:17            1                1   None

так что вы получите каждые 3 строки в пределах одного atm_id. Здесь можно использовать различные решения для использования вышеуказанной информации в df, моя задача состоит в том, чтобы идти по индексным номерам, предполагая, что они уникальны в ваших данных. Создайте mask с оригинальным индексным номером и используйте его с той же идеей, что и выше.

mask_index = df.groupby('atm_id').apply(lambda x: x.iloc[::3]).index.get_level_values(1)
#if you do print (mask_index), you get
#Out[35]: Int64Index([152865, 153054, 152806, 152866, 152887], dtype='int64')

# initiate the column
df['Period'] = None
# select every three rows within a same atm_id and assign 1 there in the column Period
df.loc[mask_index, 'Period'] = 1
# use cumsum, ffill and astype to populate have an incremental value every 3 rows
df['Period'] = df['Period'].cumsum().ffill().astype(int)

результат похож на

        atm_id     dNDCSessionTime  sCardNumber  nTrRequestCount  Period
152865       0 2017-01-14 07:56:17            1                1       1
153052       0 2017-01-14 08:01:13            1                1       1
153053       0 2017-01-14 08:02:19            1                1       1
153054       0 2017-01-14 08:03:41            1                1       2
152804       0 2017-01-14 08:04:37            1                1       2
152805       0 2017-01-14 08:05:24            1                1       2
152806       1 2017-01-14 08:06:08            1                1       3
152807       1 2017-01-14 08:07:15            1                1       3
152808       1 2017-01-14 08:08:08            1                1       3
152866       1 2017-01-14 08:08:50            1                1       4
152887       2 2017-01-12 07:56:17            1                1       5

, где вы можете увидеть приращение от 4 до 5 между двумя последними строками, в то время как для Period=4 нет 3 строк при изменении atm_id

Примечание: если ваши индексы не уникальны, то reset_index в начале и set_index в конце дают тот же результат, также я не sort_values, как вы, но это не проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...