繁体   English   中英

如何根据给定条件 pandas/python 删除 *some* 行

[英]How to remove *some* rows based on a given condition pandas/python

我正在使用 Pandas 中的数据集,我想根据给定条件删除一些行。 我的数据集中有一列是参与者的合并症数量,可能的值为 0、1、2、3。数据集大约有 100 万行(和 30 个其他列),大约 50 万参与者 = 0 合并症,约 300,000 名参与者 = 1 种合并症,约 130,000 名参与者 = 2 种合并症,约 75,000 名参与者 = 3 种合并症。 我想根据他们的合并症值随机删除参与者组,例如,删除 200k 与 0 合并症,100k 与 1 合并症。 我知道如果想放弃所有合并症数量给定的参与者,例如所有合并症为 0 的参与者,我可以执行以下操作:

dataframe = 所有部分,列名 = CM

allpart.drop(allpart[allpart['CM'] == 0].index, inplace = True) 

我怎么能改变它,让它随机 select 300k 行 w/0 合并症? 我的数据框没有按该列按升序排列,因此排除了删除一大块行的可能性,我也不确定这是否足够随机。 我还想提一下,我不会以此为依据得出任何合理的结论,这只是为了我自己的利益。

谢谢!

一种解决方案是定义您希望为每种合并症保留多少行,然后groupby + sample到 select 该大小的随机子集。

我添加了一个小检查,以防您为该'CM'组指定的行数大于 DataFrame 中存在的唯一行数。 在这种情况下,它只返回所有行。

import pandas as pd
import numpy as np
np.random.seed(410112)

df = pd.DataFrame({'id': range(20), 'CM': np.random.choice([0,1,2,3,4], 20)})
# Keys is comorbidity index, value is # of rows to keep 
d = {0: 1, 1: 3, 2: 2, 3: 20, 4: 2}

l = []
for idx, gp in df.groupby('CM'):
    try:
        gp = gp.sample(n=d[idx], replace=False)
    # If try to subsample more people than exist, do nothing
    except ValueError:
        pass 
    l.append(gp)
    
df1 = pd.concat(l)

    id  CM
3    3   0
17  17   1
13  13   1
5    5   1
19  19   2
7    7   2
1    1   3
4    4   3
10  10   3
12  12   4
0    0   4

另一种类似但不需要重建整个 DataFrame(可能更快)的替代方法是再次指定要保留的行数的字典d并使用sample(frac=1)对 DataFrame 进行洗牌,然后groupby + cumcount保留行的随机子集。

# Keys is comorbidity index, value is # of rows to keep 
d = {0: 1, 1: 3, 2: 2, 3: 20, 4: 2}

mask = df.sample(frac=1).groupby('CM', sort=False).cumcount().lt(df['CM'].map(d))
df1 = df[mask]

# Different subset of rows but still 1 row with CM0, 3 with CM1, ...

    id  CM
9    9   0
5    5   1
15  15   1
17  17   1
6    6   2
7    7   2
1    1   3
4    4   3
10  10   3
0    0   4
12  12   4

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM