Циклы for зависают при попытке использовать различные значения предыдущих строк при вычислении нового столбца. Нужно найти решение не для цикла - PullRequest
0 голосов
/ 14 октября 2019

У меня есть набор данных из 6,5 миллионов строк, в котором записано взаимодействие каждого ID пользователя с поставщиком токена. Данные отсортированы по «id» и «Days». Столбец «Days» - это количество дней с момента присоединения к поставщику.

День, в который пользователю выдаются токены, упоминается в столбце token_SUPPLY. Каждый день используется один токен.

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

Логика, которую я использовал, такова: для каждой проверки строкиесли мы все еще смотрим на тот же идентификатор пользователя. Если да, то проверьте, поставлены ли какие-либо токены, если да, то сохраните номер дня. Для каждой последующей строки того же пользователя вычислите доступные токены количество предоставленных токенов минус количество дней, прошедших с момента предоставления токенов.

currID=0
tokenSupply=0
giveDay=0
for row in df11.itertuples():
    if row.id != currID:
        tokenSupply = 0
        currID= row.id
    if row.token_SUPPLY > 0:
        giveDay=row.Days
        tokenSupply = row.token_SUPPLY
        df11.loc[row.Index,"token_onhand"]=tokenSupply
    else:
        if tokenSupply == 0:
            df11.loc[row.Index,"token_onhand"]=0
        else:
            df11.loc[row.Index,"token_onhand"]=tokenSupply-(row.Days-giveDay)

# For loop doesn't end for more than 50 minutes.

Я много читал с прошлой ночи, и этоКажется, что люди предложили использовать numpy, но я не знаю, как это сделать, потому что я только учусь использовать эти вещи. Другое предложение было @jit, но я предполагаю, что это работает, только если я определю функцию.

Другое предложение состояло в том, чтобы векторизовать, но как тогда я получу условный доступ к строкам и запомню предоставленное количество для использования вкаждый последующий ряд? Я попытался использовать np.where, но мне показалось, что он слишком запутан, чтобы обернуть вокруг него все вокруг.

Я тоже где-то готов о Cython, но опять же, я понятия не имею, как это сделать правильно.

Какой будет наилучший подход для достижения моей цели?

РЕДАКТИРОВАТЬ: добавлены примерные данные и необходимый столбец вывода

примерные выходные данные:

    id      Days  token_SUPPLY            give_event     token_onhand
190 ID1001  -12    NaN                         0           0.0
191 ID1001  -12    NaN                         0           0.0
192 ID1001  -3     NaN                         0           0.0
193 ID1001  0      5.0                         0           5.0
194 ID1001  0      5.0                         1           5.0
195 ID1001  6      NaN                         0          -1.0
196 ID1001  12     NaN                         0          -7.0
197 ID1001  12     NaN                         0          -7.0
198 ID1001  13     NaN                         0          -8.0
199 ID1001  13     NaN                         0          -8.0

Последний столбец token_onhand отсутствует в наборе данных и является тем, что на самом деле необходимо сгенерировать.

1 Ответ

0 голосов
/ 14 октября 2019

Если я правильно понимаю:

Пример данных:

       id  Days  token_SUPPLY  give_event
0   ID1001   -12           NaN           0
1   ID1001   -12           NaN           0
2   ID1001    -3           NaN           0
3   ID1001     0           5.0           0
4   ID1001     0           5.0           1
5   ID1001     6           NaN           0
6   ID1001    12           NaN           0
7   ID1001    12           NaN           0
8   ID1001    13           NaN           0
9   ID1001    13           NaN           0
10  ID1002   -12           NaN           0
11  ID1002   -12           NaN           0
12  ID1002    -3           NaN           0
13  ID1002     0           5.0           0
14  ID1002     0           5.0           1
15  ID1002     6           NaN           0
16  ID1002    12           NaN           0
17  ID1002    12           NaN           0
18  ID1002    13           NaN           0
19  ID1002    13           NaN           0

Вы можете использовать ffill для token_Supply и вычитать Days. Для более чем id используйте groupby.

df = pd.read_clipboard()
df['token_onhand'] = df.groupby('id').apply(lambda x: (x['token_SUPPLY'].ffill() - x['Days']).fillna(0)).reset_index(drop=True)

df

Результат:

        id  Days  token_SUPPLY  give_event  token_onhand
0   ID1001   -12           NaN           0           0.0
1   ID1001   -12           NaN           0           0.0
2   ID1001    -3           NaN           0           0.0
3   ID1001     0           5.0           0           5.0
4   ID1001     0           5.0           1           5.0
5   ID1001     6           NaN           0          -1.0
6   ID1001    12           NaN           0          -7.0
7   ID1001    12           NaN           0          -7.0
8   ID1001    13           NaN           0          -8.0
9   ID1001    13           NaN           0          -8.0
10  ID1002   -12           NaN           0           0.0
11  ID1002   -12           NaN           0           0.0
12  ID1002    -3           NaN           0           0.0
13  ID1002     0           5.0           0           5.0
14  ID1002     0           5.0           1           5.0
15  ID1002     6           NaN           0          -1.0
16  ID1002    12           NaN           0          -7.0
17  ID1002    12           NaN           0          -7.0
18  ID1002    13           NaN           0          -8.0
19  ID1002    13           NaN           0          -8.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...