dask 数据框应用元
dask dataframe apply meta
我想对 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#metadata)。
什么是meta
?我该如何定义它?
使用 python 3.6
dask 0.14.3
和 pandas 0.20.2
meta
是计算输出的names/types的规定。这是必需的,因为 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')))
我想对 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#metadata)。
什么是meta
?我该如何定义它?
使用 python 3.6
dask 0.14.3
和 pandas 0.20.2
meta
是计算输出的names/types的规定。这是必需的,因为 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')))