根据条件在熊猫数据框上选择行

时间:2020-05-01 15:02:44

标签: python pandas dataframe filter

我有以下代码:

import pandas as pd
import random


a = [random.randint(0, 1) for i in range(30)]
b = [random.randint(0, 1) for i in range(30)]

print(a)
print(b)

df = pd.DataFrame([a, b])
df = df.T

columns = ['column1', 'column2']
df.columns = columns
print(df)

创建一个存储在变量“ df”中的数据框。它由2列(第1列和第2列)组成,其中随机填充了0和1。

这是我在运行程序时得到的输出(如果尝试运行它,由于randomint的生成,将不会得到完全相同的结果)。

    column1  column2
0         0        1
1         1        0
2         0        1
3         1        1
4         0        1
5         1        1
6         0        1
7         1        1
8         1        0
9         0        1
10        0        0
11        1        1
12        1        1
13        0        1
14        0        0
15        0        1
16        1        1
17        1        1
18        0        1
19        1        0
20        0        0
21        1        0
22        0        1
23        1        0
24        1        1
25        0        0
26        1        1
27        1        0
28        0        1
29        1        0

我想在column2上创建一个过滤器,当连续三个或多个1时仅显示数据簇。输出将是这样的:

    column1  column2
2         0        1
3         1        1
4         0        1
5         1        1
6         0        1
7         1        1

11        1        1
12        1        1
13        0        1

15        0        1
16        1        1
17        1        1
18        0        1

为了清晰起见,我在群集之间留了一个空格,但实际输出的数据帧中没有空白。

我想通过以下方式做到这一点。

filter1 = (some boolean condition) &/| (maybe some other stuff)
final_df = df[filter1]

谢谢

1 个答案:

答案 0 :(得分:3)

我们可以使用GroupBy.transform

$('.plus').click(function () {
    addOrRemoveByOne('add');
}

$('.minus').click(function () {
    addOrRemoveByOne('remove');
}

addOrRemoveByOne(option) {
    let obj = JSON.parse(localStorage.getItem('prodOnList'));
    for (let key in obj) {
           if (option === 'add') {
               obj[key].onList += 1;
           }

           if (option === 'remove') {
               obj[key].onList -= 1;
           } 
    }
    localStorage.setItem("prodOnList", JSON.stringify(obj));}
}

输出

n = 3
blocks = df['column2'].ne(df['column2'].shift()).cumsum()
m1 = (df.groupby(blocks)['column2']
        .transform('size').ge(n))
m2 = df['column2'].eq(1)
df_filtered = df.loc[m1 & m2]
# Alternative without df['column2'].eq(1)
#df_filtered = df.loc[m1.mul(df['column2'])]
print(df_filtered)

如果您原来的DataFrame中column2实际上只包含1和0,那么我们可以使用 column1 column2 2 0 1 3 1 1 4 0 1 5 1 1 6 0 1 7 1 1 11 1 1 12 1 1 13 0 1 15 0 1 16 1 1 17 1 1 18 0 1 代替transform('sum')


每次transform('size')中的值更改时,

blocks都有一个新值

column2

替代

我经常在项目中使用此代码,得出的结论是,使用Series.map + Series.value_counts的速度通常会更快一些。两种方法之间的性能差异永远不会很大,您可以选择所需的一种。但是我通常使用我已经解释过的最后一个,我认为值得一提

print(blocks)
0      1
1      2
2      3
3      3
4      3
5      3
6      3
7      3
8      4
9      5
10     6
11     7
12     7
13     7
14     8
15     9
16     9
17     9
18     9
19    10
20    10
21    10
22    11
23    12
24    13
25    14
26    15
27    16
28    17
29    18
Name: column2, dtype: int64