【问题标题】:Pandas: Delete percentage of dataframe dependent on value change in other column熊猫:根据其他列中的值变化删除数据框的百分比
【发布时间】:2021-07-12 09:51:34
【问题描述】:

我有一个非常大的数据框(大约 50 亿行和 13 列)。其中一列的值可以是 0 和 1,分别代表非活动和活动模式。通常有几行非活动模式 (0),然后是活动模式行 (1)。所以首先有一个非活动段,然后是一个活动段,然后是一个非活动段,依此类推。

类似这样的:

df = pd.DataFrame(np.random.randint(0,100,size=(30, 4)), columns=list('ABCD'))
df['E'] = [0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0]

    A   B   C   D  E
0   53  27  10  49  0
1   39  46  89  33  0
2   32  43   7  15  0
3   16  36  33  18  0
4   12   3  94  96  1
5   31  22  64  51  1
6   79  93  93  67  1
7   85  27  10  19  1
8    4  92  38  38  1
9   79   8   6  90  1
10  68   6  26  24  1
11  89  49  23  91  1
12  44  17  40  75  1
13  12  18  17  87  1
14  76  67  74  15  0
15   9  37   8  92  0
16  52  53  93  47  0
17  74   3  27  96  0
18  77  10  93   8  0
19  64  33  46  79  0
20  72   9  36  99  0
21  75  13  76  49  1
22  95  21  88  77  1
23  46  45  36  20  1
24  61  26  72  48  1
25  35  62  98  28  1
26  91  43  23  42  0
27  25  59   6  30  0
28  20  31   2  76  0
29   2  25  86  12  0

我需要删除每个活动段的前 20%,非活动段应保持原样。所以它应该是这样的:

    A   B   C   D  E
0   53  27  10  49  0
1   39  46  89  33  0
2   32  43   7  15  0
3   16  36  33  18  0
6   79  93  93  67  1
7   85  27  10  19  1
8    4  92  38  38  1
9   79   8   6  90  1
10  68   6  26  24  1
11  89  49  23  91  1
12  44  17  40  75  1
13  12  18  17  87  1
14  76  67  74  15  0
15   9  37   8  92  0
16  52  53  93  47  0
17  74   3  27  96  0
18  77  10  93   8  0
19  64  33  46  79  0
20  72   9  36  99  0
22  95  21  88  77  1
23  46  45  36  20  1
24  61  26  72  48  1
25  35  62  98  28  1
26  91  43  23  42  0
27  25  59   6  30  0
28  20  31   2  76  0
29   2  25  86  12  0

我已经使用 df.diff() 添加了一个附加列,它显示了从非活动到活动的变化发生的位置,反之亦然:

     A   B   C   D  E  E_diff
0   53  27  10  49  0     NaN
1   39  46  89  33  0     0.0
2   32  43   7  15  0     0.0
3   16  36  33  18  0     0.0
4   12   3  94  96  1     1.0
5   31  22  64  51  1     0.0
6   79  93  93  67  1     0.0
7   85  27  10  19  1     0.0
8    4  92  38  38  1     0.0
9   79   8   6  90  1     0.0
10  68   6  26  24  1     0.0
11  89  49  23  91  1     0.0
12  44  17  40  75  1     0.0
13  12  18  17  87  1     0.0
14  76  67  74  15  0    -1.0
15   9  37   8  92  0     0.0
16  52  53  93  47  0     0.0
17  74   3  27  96  0     0.0
18  77  10  93   8  0     0.0
19  64  33  46  79  0     0.0
20  72   9  36  99  0     0.0
21  75  13  76  49  1     1.0
22  95  21  88  77  1     0.0
23  46  45  36  20  1     0.0
24  61  26  72  48  1     0.0
25  35  62  98  28  1     0.0
26  91  43  23  42  0    -1.0
27  25  59   6  30  0     0.0
28  20  31   2  76  0     0.0
29   2  25  86  12  0     0.0

我不知道如何确定段的长度,然后删除正确的行。我需要为此编写一个循环还是有更简单的方法?以及如何确定要删除的行的正确索引值?

【问题讨论】:

标签: python pandas dataframe drop


【解决方案1】:

这可以完成工作。这是两个独立 StackOverflow 答案的拼凑:stackoverflow.com/a/45886579/7483211https://stackoverflow.com/a/31226290/7483211

df['flag'] = df.E.diff().ne(0).cumsum()

def mask_first(x,ratio=0.2):
    result = np.ones_like(x,dtype=bool)
    result[0:math.ceil(len(x)*ratio)] = False 
    return result

mask = df.groupby(['flag'])['flag'].transform(mask_first).astype(bool)
df[(df.E == 0) | mask].drop('flag',axis=1)

输出是:

idx A   B   C   D   E
0   77  44  52  17  0
1   75  61  69  6   0
2   79  87  99  31  0
3   42  10  3   98  0
6   53  68  86  92  1
7   25  3   27  84  1
8   18  60  93  79  1
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-02
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多