如何随机选择一些pandas数据帧的行?

3

我有一个名为df的pandas数据帧,其中包含一个名为amount的列。对于许多行,amount为零。我想随机删除其中 50% 的 amount 为零的行,并保留所有amount不为零的行。如何操作?

2个回答

3

pandas

使用 query + sample 方法

df.drop(df.query('amount == 0').sample(frac=.5).index)

考虑数据框 df
df = pd.DataFrame(dict(amount=[0, 1] * 10))

df.drop(df.query('amount == 0').sample(frac=.5).index)

numpy

iszero = df.amount.values == 0
count_zeros = iszero.sum()
idx = np.arange(iszero.shape[0])
keep_these = np.random.choice(idx[iszero], int(iszero.sum() * .5), replace=False)

df.iloc[np.sort(np.concatenate([idx[~iszero], keep_these]))]

    amount
1        1
2        0
3        1
5        1
6        0
7        1
8        0
9        1
10       0
11       1
12       0
13       1
15       1
17       1
19       1

时间测试

enter image description here

根据@tomcy的评论,您可以使用inplace=True参数从df中删除行,而无需重新分配df

df.drop(df.query('amount == 0').sample(frac=.5).index, inplace=True)
df

    amount
1        1
2        0
3        1
5        1
6        0
7        1
8        0
9        1
10       0
11       1
12       0
13       1
15       1
17       1
19       1


1
inplace parameter should be True - tomcy
1
对于性能而言,进行布尔选择似乎比查询快大约两倍(当然仍然慢于numpy):df.drop(df[df.amount == 0].sample(frac=.5).index) - JohnE
1
@JohnE 是的!我发现如果我要为了速度而偏离我所钟爱的“查询”,那么我不妨走得更远 :-). 另外...这也为其他人发布答案留下了机会,如果你明白我的意思的话。OP甚至可能更喜欢那个答案。 - piRSquared
好的,我会将它写成你答案的调整版。 - JohnE

2
@piRSquared的答案稍作修改(使用布尔选择而不是查询):
df.drop( df[df.amount == 0].sample(frac=.5).index )

这种方法比使用query快大约两倍,但比numpy慢3倍。


1
这很棒,因为很多人希望得到更直观的 pandas 答案。有些人甚至可能更喜欢这种语法而不是 query - piRSquared
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - royco
1
@royco 谢谢,不用担心。你做出了正确的选择。我只是对piRSquared的答案进行了微小的调整。 - JohnE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接