根据Python中的分组列值执行条件筛选
我想对Sales列执行筛选,以便对于任何Make拍卖组,至少有一个Sales大于等于100。因此,对于Acura而言,Copart的销售额为101,因此预计Acura的两行产品都将出现在产量中。对于宝马来说,整个销售栏的销售额是100,但这不是我想要的。有没有关于如何执行此操作的建议?谢谢 过滤数据框中销售>=100的记录,然后获取汽车的唯一根据Python中的分组列值执行条件筛选,python,pandas,Python,Pandas,我想对Sales列执行筛选,以便对于任何Make拍卖组,至少有一个Sales大于等于100。因此,对于Acura而言,Copart的销售额为101,因此预计Acura的两行产品都将出现在产量中。对于宝马来说,整个销售栏的销售额是100,但这不是我想要的。有没有关于如何执行此操作的建议?谢谢 过滤数据框中销售>=100的记录,然后获取汽车的唯一Make。最后,如果此筛选集中有任何make,请使用布尔索引 >>> df[df['Make'].isin(df[df['Sales']
Make
。最后,如果此筛选集中有任何make,请使用布尔索引
>>> df[df['Make'].isin(df[df['Sales'] >= 100]['Make'].unique())]
Make Auction Sales
0 Acura Copart 101
1 Acura IAA 88
4 Buick Copart 130
5 Buick IAA 140
使用:
另一种解决方案,使用和为生成
值,这些值通过以下方式过滤:
第二种解决方案更快:
np.random.seed(123)
N = 1000000
L = list('abcdefghijklmno')
df = pd.DataFrame({'Make': np.random.choice(L, N),
'Sales':np.random.randint(110, size=N)})
print (df)
In [59]: %timeit df[df['Make'].isin(df.loc[df['Sales'] >= 100, 'Make'])]
10 loops, best of 3: 55.6 ms per loop
#Alexander answer
In [60]: %timeit df[df['Make'].isin(df[df['Sales'] >= 100]['Make'].unique())]
10 loops, best of 3: 65 ms per loop
In [61]: %timeit df.groupby('Make').filter(lambda x: x['Sales'].ge(100).any())
1 loop, best of 3: 217 ms per loop
#piRSquared solution 1
In [62]: %timeit df[df.Sales.ge(100).groupby([df.Make]).transform('any')]
1 loop, best of 3: 135 ms per loop
#piRSquared solution 2
In [63]: %%timeit
...: f, u = pd.factorize(df.Make.values)
...: w = df.Sales.values >= 100
...: df[(np.bincount(f, w) > 0)[f]]
...:
10 loops, best of 3: 67.2 ms per loop
选项1
转换
使用
'any'
返回True
如果组中有任何元素True
,并在组中的所有索引中广播该元素
df[df.Sales.ge(100).groupby([df.Make]).transform('any')]
Make Auction Sales
0 Acura Copart 101
1 Acura IAA 88
4 Buick Copart 130
5 Buick IAA 140
选项2
+
我们使用
np.bincount
从pd.factorize
增加仓位,其真值由df.Sales.values>=100
确定。如果bin大于0
,那么我们应该获取该bin定义的组中的每个元素。我们可以通过f
再次切片得到合适的数组
这与选项1非常类似
f, u = pd.factorize(df.Make.values)
w = df.Sales.values >= 100
df[(np.bincount(f, w) > 0)[f]]
Make Auction Sales
0 Acura Copart 101
1 Acura IAA 88
4 Buick Copart 130
5 Buick IAA 140
有趣。你能详细说明一下变换中的任何吗?“更快”完全取决于
N
,不确定,为了更好地进行测试,必须知道中唯一值的数量、组的长度、数据帧的长度。但是显然,loc
有助于提高性能。使用loc
似乎不会影响性能,但我认为改进是微不足道的。
print (df.loc[df['Sales'] >= 100, 'Make'])
0 Acura
4 Buick
5 Buick
Name: Make, dtype: object
print (df['Make'].isin(df.loc[df['Sales'] >= 100, 'Make']))
0 True
1 True
2 False
3 False
4 True
5 True
Name: Make, dtype: bool
df = df[df['Make'].isin(df.loc[df['Sales'] >= 100, 'Make'])]
print (df)
Make Auction Sales
0 Acura Copart 101
1 Acura IAA 88
4 Buick Copart 130
5 Buick IAA 140
np.random.seed(123)
N = 1000000
L = list('abcdefghijklmno')
df = pd.DataFrame({'Make': np.random.choice(L, N),
'Sales':np.random.randint(110, size=N)})
print (df)
In [59]: %timeit df[df['Make'].isin(df.loc[df['Sales'] >= 100, 'Make'])]
10 loops, best of 3: 55.6 ms per loop
#Alexander answer
In [60]: %timeit df[df['Make'].isin(df[df['Sales'] >= 100]['Make'].unique())]
10 loops, best of 3: 65 ms per loop
In [61]: %timeit df.groupby('Make').filter(lambda x: x['Sales'].ge(100).any())
1 loop, best of 3: 217 ms per loop
#piRSquared solution 1
In [62]: %timeit df[df.Sales.ge(100).groupby([df.Make]).transform('any')]
1 loop, best of 3: 135 ms per loop
#piRSquared solution 2
In [63]: %%timeit
...: f, u = pd.factorize(df.Make.values)
...: w = df.Sales.values >= 100
...: df[(np.bincount(f, w) > 0)[f]]
...:
10 loops, best of 3: 67.2 ms per loop
df[df.Sales.ge(100).groupby([df.Make]).transform('any')]
Make Auction Sales
0 Acura Copart 101
1 Acura IAA 88
4 Buick Copart 130
5 Buick IAA 140
f, u = pd.factorize(df.Make.values)
w = df.Sales.values >= 100
df[(np.bincount(f, w) > 0)[f]]
Make Auction Sales
0 Acura Copart 101
1 Acura IAA 88
4 Buick Copart 130
5 Buick IAA 140