Как отбросить определенные значения после проверки условия во втором столбце?

Принимая df следующим образом:

Product    Time
   1         1
   1         2
   1         3
   1         4
   2         1
   2         2
   2         3
   2         4
   2         5
   2         6
   2         7
   3         1
   3         2
   3         3
   4         1
   4         2
   4         3

Я хотел бы оставить только те Product которых Time больше 3, и отбросить остальные. В приведенном выше примере, после того, как я

df.groupby(['Product']).size()

Я получаю следующий вывод:

1    4
2    7
3    3
4    3

и исходя из этого, из моего основного df, я хотел бы только сохранить продукт 1 и 2

Ожидаемый результат:

     Product    Time
       1         1
       1         2
       1         3
       1         4
       2         1
       2         2
       2         3
       2         4
       2         5
       2         6
       2         7

Всего 3 ответа


Используйте GroupBy.transform для возвращаемых Series с таким же размером, как у оригинала, поэтому возможна фильтрация с помощью boolean indexing :

df = df[df.groupby(['Product'])['Product'].transform('size') > 3]
print (df)
    Product  Time
0         1     1
1         1     2
2         1     3
3         1     4
4         2     1
5         2     2
6         2     3
7         2     4
8         2     5
9         2     6
10        2     7

Детали :

b = df.groupby(['Product'])['Product'].transform('size') > 3
a = df.groupby(['Product'])['Product'].transform('size')

print (df.assign(size=a, filter=b))
    Product  Time  size  filter
0         1     1     4    True
1         1     2     4    True
2         1     3     4    True
3         1     4     4    True
4         2     1     7    True
5         2     2     7    True
6         2     3     7    True
7         2     4     7    True
8         2     5     7    True
9         2     6     7    True
10        2     7     7    True
11        3     1     3   False
12        3     2     3   False
13        3     3     3   False
14        4     1     3   False
15        4     2     3   False
16        4     3     3   False

Если DataFrame не велик, вот альтернатива DataFrameGroupBy.filter :

df = df.groupby(['Product']).filter(lambda x: len(x) > 3)

Вместо этого используйте transform.size после группировки, проверьте, что больше ( gt ) 3, и используйте результат для выполнения логического индексирования на вашем фрейме данных:

df[df.groupby('Product').Time.transform('size').gt(3)]

      Product  Time
0         1     1
1         1     2
2         1     3
3         1     4
4         2     1
5         2     2
6         2     3
7         2     4
8         2     5
9         2     6
10        2     7

Вы можете сделать это, если вы не планируете использовать операцию assign и хотите использовать boolean indexing .

g = df.groupby('Product')
t = g.transform('count')
df['c']=t #new column holding the count
df2=df[df['c'] > 3]
print(df2)

    Product  Time
0         1     1
1         1     2
2         1     3
3         1     4
4         2     1
5         2     2
6         2     3
7         2     4
8         2     5
9         2     6
10        2     7
11        3     1
12        3     2
13        3     3
14        4     1
15        4     2
16        4     3
    Product  Time  c
0         1     1  4
1         1     2  4
2         1     3  4
3         1     4  4
4         2     1  7
5         2     2  7
6         2     3  7
7         2     4  7
8         2     5  7
9         2     6  7
10        2     7  7

Есть идеи?

10000