假设我有此数据:
data = {
'batch_no': [42, 42, 52, 52, 52, 73],
'quality': ['OK', 'NOT OK', 'OK', 'NOT OK', 'NOT OK', 'OK'],
}
df = pd.DataFrame(data, columns = ['batch_no', 'quality'])
这为我提供了以下数据框
batch_no quality
42 OK
42 NOT OK
52 OK
52 NOT OK
52 NOT OK
73 OK
现在我需要为每个NOT OK
找到batch_no
的计数。
我可以使用groupby
和apply
通过lamda
函数来实现此目的,如下所示:
df.groupby('batch_no')['quality'].apply(lambda x: x[x.eq('NOT OK')].count())
这给了我以下期望的输出
batch_no
42 1
52 2
73 0
但是,即使在我大约300万行的中等大小的数据上,这也非常慢,并且不能满足我的需求。
是否有一种快速的替代方法?
答案 0 :(得分:3)
您可以比较列quality
,然后按batch_no
比较groupby
并汇总sum
,True
的过程类似于1
,因此算在内值:
df = df['quality'].eq('NOT OK')
.groupby(df['batch_no']).sum()
.astype(int)
.reset_index(name='count')
print (df)
batch_no count
0 42 1
1 52 2
2 73 0
详细信息:
print (df['quality'].eq('NOT OK'))
0 False
1 True
2 False
3 True
4 True
5 False
Name: quality, dtype: bool
答案 1 :(得分:3)
您可以使用
In [77]: df.quality.eq('NOT OK').groupby(df.batch_no).sum()
Out[77]:
batch_no
42 1.0
52 2.0
73 0.0
Name: quality, dtype: float64
答案 2 :(得分:3)
这将提供所有值计数
df.groupby('batch_no').quality.value_counts().unstack(fill_value=0)
Out[231]:
quality NOT OK OK
batch_no
42 1 1
52 2 1
73 0 1
使用crosstab
pd.crosstab(df.batch_no,df.quality)
Out[242]:
quality NOT OK OK
batch_no
42 1 1
52 2 1
73 0 1
答案 3 :(得分:3)
使用pd.factorize
和np.bincount
f, u = pd.factorize(df.batch_no)
pd.Series(np.bincount(f, df.quality.eq('NOT OK')).astype(int), u)
42 1
52 2
73 0
dtype: int64
合并'OK'
(受Wen启发)
i, r = pd.factorize(df.batch_no)
j = df.quality.eq('NOT OK')
pd.DataFrame(
np.bincount(i * 2 + j, minlength=len(r) * 2).reshape(len(r), -1),
r, ['OK', 'NOT OK']
)
OK NOT OK
42 1 1
52 1 2
73 1 0