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

Я хочу отбросить каждого пользователя, который делает менее 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().

1
Nirmine 3 Май 2019 в 01:48

3 ответа

Лучший ответ

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

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

operations_per_user.index[operations_per_user <= 3]

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

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

ИЗМЕНИТЬ

Насколько я понимаю, вы хотите удалить любого пользователя, который встречается в данных менее 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
razdi 3 Май 2019 в 01:13

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

Сначала выберите пользователя, которого хотите оставить.
Затем получите логический список, длина которого равна 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
Valentino 3 Май 2019 в 00:54
  • Если 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 и {{ X4}}, и здесь является Отличная таблица панд для справки.

  • Вы можете использовать списки Python в качестве итераторов; для вашего второго цикла:
for user in undesirable_users:
    data = data.drop(data.loc[data['user_id'] == user].index)
0
Dagorodir 3 Май 2019 в 00:28