Dask 包到 Dataframe 问题
Dask bag to Dataframe Issue
我有键值格式的数据。我创建了一个 dask 包,然后从该包创建了一个数据框。但是当我尝试对该数据框进行分组时,它会抛出错误。但是对于相同的数据,当我直接创建 pandas 数据框或 dask 数据框时,它工作正常。
我想我错过了什么。请帮助!!!
我在下面的代码中重现了这个问题。
import pandas as pd
import dask.dataframe as dd
import dask.bag as db
df = pd.DataFrame({'A': [1, 1, 2, None], 'B': [1, 2, 3, 4]})
df.groupby(df.A).count() # pandas, working
ddf = dd.from_pandas(df, 2)
ddf.groupby(ddf.A).count().compute() # dask dataframe, working
bg = db.from_sequence([{'A': 1,'B':1}, {'A': 1,'B': 2}, {'A': 2,'B':3 }, {'A': None, 'B': 4}])
ddf_2 = bg.to_dataframe()
ddf_2 = ddf_2.fillna(0)
ddf_2.groupby(ddf_2.A).count().compute() # throws error
..........
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
注意:在实际情况下,我在 avro 文件中有数据。所以我不能跳过 dask 包到数据框部分。
问题是 认为 你拥有的数据类型并不是你实际 拥有的数据类型。当你 Bag.to_dataframe
没有指定输出 dtypes 时,dask 假设第一个分区是有代表性的(加载整个数据集来检查是昂贵的)并从中推断数据帧 dtypes,从而推断 'A'
作为一个整数列.
In [1]: import dask.bag as db
In [2]: bg = db.from_sequence([{'A': 1,'B':1}, {'A': 1,'B': 2}, {'A': 2,'B':3 }, {'A': None, 'B': 4}])
In [3]: ddf = bg.to_dataframe()
In [4]: ddf.dtypes
Out[4]:
A int64
B int64
dtype: object
实际上'A'
后面虽然有缺失值,所以不能是整数列(pandas整数系列目前没有缺失值表示,必须使用浮点数)。为了在这里变得健壮,您应该使用 meta
关键字指定预期数据帧的数据类型:
In [5]: ddf = bg.to_dataframe(meta={'A': float, 'B': int}) # specify 'A' has missing values and must be float
In [6]: ddf2 = ddf.fillna(0).astype({'A': int}) # fill missing with 0, and convert A back to int
In [7]: ddf2.groupby(ddf2.A).count().compute()
Out[7]:
B
A
1 2
2 1
0 1
有关详细信息,请参阅 Bag.to_dataframe 的文档字符串。
我有键值格式的数据。我创建了一个 dask 包,然后从该包创建了一个数据框。但是当我尝试对该数据框进行分组时,它会抛出错误。但是对于相同的数据,当我直接创建 pandas 数据框或 dask 数据框时,它工作正常。
我想我错过了什么。请帮助!!!
我在下面的代码中重现了这个问题。
import pandas as pd
import dask.dataframe as dd
import dask.bag as db
df = pd.DataFrame({'A': [1, 1, 2, None], 'B': [1, 2, 3, 4]})
df.groupby(df.A).count() # pandas, working
ddf = dd.from_pandas(df, 2)
ddf.groupby(ddf.A).count().compute() # dask dataframe, working
bg = db.from_sequence([{'A': 1,'B':1}, {'A': 1,'B': 2}, {'A': 2,'B':3 }, {'A': None, 'B': 4}])
ddf_2 = bg.to_dataframe()
ddf_2 = ddf_2.fillna(0)
ddf_2.groupby(ddf_2.A).count().compute() # throws error
..........
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
注意:在实际情况下,我在 avro 文件中有数据。所以我不能跳过 dask 包到数据框部分。
问题是 认为 你拥有的数据类型并不是你实际 拥有的数据类型。当你 Bag.to_dataframe
没有指定输出 dtypes 时,dask 假设第一个分区是有代表性的(加载整个数据集来检查是昂贵的)并从中推断数据帧 dtypes,从而推断 'A'
作为一个整数列.
In [1]: import dask.bag as db
In [2]: bg = db.from_sequence([{'A': 1,'B':1}, {'A': 1,'B': 2}, {'A': 2,'B':3 }, {'A': None, 'B': 4}])
In [3]: ddf = bg.to_dataframe()
In [4]: ddf.dtypes
Out[4]:
A int64
B int64
dtype: object
实际上'A'
后面虽然有缺失值,所以不能是整数列(pandas整数系列目前没有缺失值表示,必须使用浮点数)。为了在这里变得健壮,您应该使用 meta
关键字指定预期数据帧的数据类型:
In [5]: ddf = bg.to_dataframe(meta={'A': float, 'B': int}) # specify 'A' has missing values and must be float
In [6]: ddf2 = ddf.fillna(0).astype({'A': int}) # fill missing with 0, and convert A back to int
In [7]: ddf2.groupby(ddf2.A).count().compute()
Out[7]:
B
A
1 2
2 1
0 1
有关详细信息,请参阅 Bag.to_dataframe 的文档字符串。