Je veux faire un comptage de fréquence sur une seule colonne d'une trame de données dask
. Le code fonctionne, mais j'obtiens un warning
me plaignant que meta
n'est pas défini. Si j'essaie de définir meta
j'obtiens une erreur AttributeError: 'DataFrame' object has no attribute 'name'
. Pour ce cas d'utilisation particulier, il ne semble pas que je doive définir meta
mais j'aimerais savoir comment le faire pour référence future.
Cadre de données fictif et fréquences des colonnes
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
Essayer de définir meta
produit AttributeError
(dask_df.groupby('Column B')
.apply(lambda d: len(d), meta={'Column B': 'int'})).compute()
pareil pour ça
(dask_df.groupby('Column B')
.apply(lambda d: len(d), meta=pd.DataFrame({'Column B': 'int'}))).compute()
même si j'essaye d'avoir dtype
être int
au lieu de "int"
ou d'ailleurs 'f8'
ou np.float64
donc il ne semble pas que ce soit le dtype
qui soit à l'origine du problème.
La documentation sur meta
semble impliquer que je devrais faire exactement ce que j'essaie de faire ( http://dask.pydata.org/en/latest/dataframe-design.html# métadonnées ).
Qu'est-ce que meta
? et comment suis-je censé le définir?
En utilisant python 3.6
dask 0.14.3
et pandas 0.20.2
meta
est la prescription des noms/types de la sortie du calcul. Ceci est nécessaire car apply()
est suffisamment flexible pour produire à peu près n'importe quoi à partir d'une trame de données. Comme vous pouvez le voir, si vous ne fournissez pas de meta
, alors dask calcule en fait une partie des données, pour voir quels types devraient être - ce qui est bien, mais vous devez savoir que cela se produit. Vous pouvez éviter ce précalcul (qui peut être coûteux) et être plus explicite lorsque vous savez à quoi devrait ressembler la sortie, en fournissant une version à zéro ligne de la sortie (trame de données ou série), ou simplement les types.
La sortie de votre calcul est en fait une série, donc ce qui suit est le plus simple qui fonctionne
(dask_df.groupby('Column B')
.apply(len, meta=('int'))).compute()
mais plus précis serait
(dask_df.groupby('Column B')
.apply(len, meta=pd.Series(dtype='int', name='Column B')))