如何基于给定条件/python删除*some*行

2024-10-01 07:40:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理Pandas中的一个数据集,我想根据给定的条件删除一些行。我的数据集中有一列是参与者共病的数量,可能的值是0,1,2,3。该数据集大约有100万行(和30个其他列),其中约500k参与者=0个共病,约300K参与者=1个共病,约130K参与者=2个共病,约75k参与者=3个共病。我想根据他们的共病值随机删除参与者组,例如,0共病删除200k,1共病删除100k。我知道如果要删除所有患有给定数量共病的参与者,例如,所有患有0种共病的参与者,我可以执行以下操作:

dataframe=allpart,列名=CM

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

我如何改变它,使其随机选择30万行w/0共病?我的数据帧不是按该列的升序排列的,因此排除了删除一大块行的可能性。我也不确定这是否足够随机。我还想指出,我不会利用这一点从中得出任何合法的结论,这完全是为了我自己的利益

谢谢大家!


Tags: 数据truedataframepandas数量indexcm条件
1条回答
网友
1楼 · 发布于 2024-10-01 07:40:00

一种解决方案是定义每个共病要保留多少行,然后groupby+sample选择该大小的随机子集

我添加了一个小检查,以防指定的行数大于该'CM'组的数据帧中存在的唯一行数。在本例中,它只返回所有行

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

另一种类似但不需要重建整个数据帧(可能更快)的替代方法是再次指定要保留的行数的字典d,并使用sample(frac=1)洗牌数据帧,然后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

相关问题 更多 >