我有一个数据集,我想用一种更快的方法删除一些行。我尝试了以下代码,但是花了很长时间
我想删除所有进行少于3次操作的用户。
每个操作都存储在一行中,其中user_id不是我的数据的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()
创建的系列。
答案 0 :(得分:0)
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
。 This是loc
和iloc
的一个很好的总结,而here是一个很棒的熊猫速查表。
for user in undesirable_users:
data = data.drop(data.loc[data['user_id'] == user].index)
答案 1 :(得分:0)
为什么不仅仅过滤它们?您根本不需要循环。
您可以通过以下方式获取过滤索引:
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)]
答案 2 :(得分:0)
您无需删除,只需选择要保持逻辑状态的行即可。
首先,选择仅保留的用户。
然后获得一个布尔列表,其长度等于data
行。
最后,选择要保留的行。
keepusers = operation_per_user.loc[operation_per_user > 3]
tokeep = [uid in keepuser for uid in data['user_id']]
newdata = data.loc[tokeep]