Как быстрее удалить серию строк из фрейма данных - PullRequest
1 голос
/ 03 мая 2019

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

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

каждая операция сохраняется в строке, в которой user_id не является идентификатором моих данных

undesirable_users=[] 
for i in range(len(operations_per_user)):
    if operations_per_user.get_value(operations_per_user.index[i])<=3:
        undesirable_users.append(operations_per_user.index[i])

for i in range(len(undesirable_users)):
    data = data.drop(data[data.user_id == undesirable_users[i]].index)

data - это кадр данных, а operation_per_user - серия, созданная: operation_per_user = data['user_id'].value_counts().

Ответы [ 3 ]

0 голосов
/ 03 мая 2019

Почему бы просто не отфильтровать их? Вам вообще не нужно зацикливаться.

Отфильтрованные индексы можно получить по:

operations_per_user.index[operations_per_user <= 3]

И затем вы можете отфильтровать эти индексы из df, приняв решение:

data = data[data['user_id'] not in (operations_per_user.index[operations_per_user <= 3])]

EDIT

Насколько я понимаю, вы хотите удалить любого пользователя, который встречается в данных менее 3 раз. Вам не нужно будет создавать список value_counts для этого, вы можете сделать groupby и найти счетчики, а затем отфильтровать их на этом основании.

filtered_user_ids = data.groupby('user_id').filter(lambda x: len(x) <= 3)['user_id'].tolist()

data = data[~data[user_id].isin(filtered_user_ids)]
0 голосов
/ 03 мая 2019

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

Сначала выберите пользователя, которого хотите оставить.
Затем получите логический список, длина которого равна data строк.
Наконец, выберите строки для сохранения.

keepusers = operation_per_user.loc[operation_per_user > 3]
tokeep = [uid in keepuser for uid in data['user_id']]
newdata = data.loc[tokeep]
0 голосов
/ 03 мая 2019
  • Если data - это панда DataFrame, и она содержит как user_id, так и operations_per_user как столбцы, вы должны выполнить удаление с помощью:
data = data.drop(data.loc[data['operations_per_user'] <= 3].index)

Редактировать

Вместо создания отдельной серии вы можете добавить operations_per_user к data с помощью:

data['operations_per_user'] = data.loc[:, 'user_id'].value_counts()

Вы можете выполнить сброс, как указано выше, или выполнить выборку с обратным логическим условием:

data = data.loc[data['operations_per_user' > 3]]

Оригинал

Было бы предпочтительнее, если бы вы могли предоставить больше информации о переменных, используемых в вашем коде.

  • Если operations_per_user - это панда Series, ваш первый цикл может быть улучшен с помощью:
undesirable_users=[] 
for i in operations_per_user.index:
    if operations_per_user.loc[i] <= 3:
        undesirable_users.append(i)

Функция get_value() устарела, вместо нее используйте loc или iloc. Это - хорошее обобщение loc и iloc, а здесь - отличная таблица панд для справки.

  • Вы можете использовать списки Python в качестве итераторов; для вашего второго цикла:
for user in undesirable_users:
    data = data.drop(data.loc[data['user_id'] == user].index)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...