dask
データフレームの単一の列で頻度をカウントしたいのですが。コードは機能しますが、warning
が定義されていないという不満がmeta
に出ます。 meta
を定義しようとすると、エラーAttributeError: 'DataFrame' object has no attribute 'name'
が発生します。この特定の使用例では、meta
を定義する必要があるようには見えませんが、将来の参照のためにその方法を知りたいのです。
ダミーデータフレームと列の頻度
import pandas as pd
from dask import dataframe as dd
df = pd.DataFrame([['Sam', 'Alex', 'David', 'Sarah', 'Alice', 'Sam', 'Anna'],
['Sam', 'David', 'David', 'Alice', 'Sam', 'Alice', 'Sam'],
[12, 10, 15, 23, 18, 20, 26]],
index=['Column A', 'Column B', 'Column C']).T
dask_df = dd.from_pandas(df)
In [39]: dask_df.head()
Out[39]:
Column A Column B Column C
0 Sam Sam 12
1 Alex David 10
2 David David 15
3 Sarah Alice 23
4 Alice Sam 18
(dask_df.groupby('Column B')
.apply(lambda group: len(group))
).compute()
UserWarning: `meta` is not specified, inferred from partial data. Please provide `meta` if the result is unexpected.
Before: .apply(func)
After: .apply(func, meta={'x': 'f8', 'y': 'f8'}) for dataframe result
or: .apply(func, meta=('x', 'f8')) for series result
warnings.warn(msg)
Out[60]:
Column B
Alice 2
David 2
Sam 3
dtype: int64
meta
を定義しようとすると、AttributeError
が生成されます
(dask_df.groupby('Column B')
.apply(lambda d: len(d), meta={'Column B': 'int'})).compute()
これも同じ
(dask_df.groupby('Column B')
.apply(lambda d: len(d), meta=pd.DataFrame({'Column B': 'int'}))).compute()
dtype
を"int"
の代わりにint
にしようとする場合も同じです。つまり、'f8'
またはnp.float64
の場合は、 dtype
それが問題の原因です。
meta
に関するドキュメントは、私がやろうとしていることを正確に実行する必要があることを示唆しているようです( http://dask.pydata.org/en/latest/dataframe-design.html#メタデータ )。
meta
とは何ですか?そして、私はそれをどのように定義するべきですか?
python 3.6
dask 0.14.3
およびpandas 0.20.2
の使用
meta
は、計算からの出力の名前/タイプの処方です。 apply()
は、データフレームからほとんど何でも生成できるほど柔軟であるため、これが必要です。ご覧のとおり、meta
を指定しない場合、daskは実際にデータの一部を計算して、タイプが何であるかを確認します。これは問題ありませんが、発生していることを知っている必要があります。この事前計算(コストが高くなる可能性があります)を回避し、出力のゼロ行バージョン(データフレームまたはシリーズ)またはタイプのみを提供することにより、出力がどのように見えるかがわかっている場合により明示的にすることができます。
あなたの計算の出力は実際にはシリーズなので、以下は最も簡単に機能します
(dask_df.groupby('Column B')
.apply(len, meta=('int'))).compute()
しかし、より正確になります
(dask_df.groupby('Column B')
.apply(len, meta=pd.Series(dtype='int', name='Column B')))