Pandas:根据其他列中的值更改删除数据框的百分比
Pandas: Delete percentage of dataframe dependent on value change in other column
我有一个非常大的数据框(大约 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
我不知道如何确定段的长度,然后删除正确的行。我需要为此编写一个循环还是有更简单的方法?我如何确定要删除的行的正确索引值?
这样就可以了。这是两个独立的 Whosebug 答案的拼凑而成: and :
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
...
我有一个非常大的数据框(大约 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
我不知道如何确定段的长度,然后删除正确的行。我需要为此编写一个循环还是有更简单的方法?我如何确定要删除的行的正确索引值?
这样就可以了。这是两个独立的 Whosebug 答案的拼凑而成:
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
...