在dask.dataframe中计算特定值的出现次数

3

I have a dataframe like this:

df.head()
   day      time  resource_record  
0   27  00:00:00             AAAA  
1   27  00:00:00                A  
2   27  00:00:00             AAAA  
3   27  00:00:01                A  
4   27  00:00:02                A  

我想找出某些resource_records出现的次数。

我的第一次尝试是使用value_counts()返回的Series,看起来很不错,但是后来发现无法排除一些标签,因为dask.Series中没有实现drop()方法。

所以我尝试只打印所需标签:

for row in df.resource_record.value_counts().iteritems():
    if row[0] in ['AAAA']:
        continue
    print('\t{0}\t{1}'.format(row[1], row[0]))

这个方法可以正常工作,但是如果我想要进一步处理这些数据并真正清理它们呢?所以我搜索了一下文档,发现了mask(),但这种方法也有点笨拙:

records = df.resource_record.mask(df.resource_record.map(lambda x: x in ['AAAA'])).value_counts()

我正在寻找一种方法,可以只计算单个值,但是count()会计算所有不是NaN的值。

然后我发现了str.contains(),但我不知道如何处理此代码返回的未记录标量类型:

print(df.resource_record.str.contains('A').sum())

输出:

dd.Scalar<series-..., dtype=int64>

但是即使查看了Scalar在dask/dataframe/core.py中的代码,我也没有找到获取它的值的方法。

你如何高效地计算数据框中特定值集合的出现次数?


在弄清楚这个问题时,我意识到 dask.dataframe.drop 仅支持 axis=1。在数据框上进行删除可能是一种解决方案。 - vollkorn
要获取标量(或任何其他dask集合)的值,您需要使用方法.compute() - mdurant
啊,谢谢。我之前遇到过.compute(),但是从文档中没有明确得知它将对我有所帮助。 - vollkorn
2个回答

5
在大多数情况下,pandas的语法同样适用于dask,只需添加.compute()(或dask.compute)以实际执行操作。在计算之前,您仅构造了定义操作的图表。
我认为您问题的最简单解决方案是这样的:
df[df.resource_record!='AAAA'].resource_record.value_counts().compute()

选择器方括号中的表达式可以是一些映射或函数。

在'[]'中的')'有一个小拼写错误。 - vollkorn
这个很好用。我想我只是对如何使用pandas/dask不太有经验。谢谢。 - vollkorn

1

我发现一个非常不错的方法,就是这个:

counts = df.resource_record.mask(df.resource_record.isin(['AAAA'])).dropna().value_counts()

首先,我们掩盖所有需要删除的条目,将其值替换为NaN。然后,我们删除所有带有NaN的行,并最后计算唯一值的出现次数。

这需要 df 没有 NaN 值,否则会导致包含 NaN 的行也被删除。

我期望得到类似以下的结果

df.resource_record.drop(df.resource_record.isin(['AAAA']))

我认为使用 drop 操作会更快,因为它只需要一次遍历数据集,而 mask + dropna 需要两次。但是,drop 操作只适用于 axis=1,而我们这里需要的是 axis=0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接