Python 基于2个现有列的值为dask数据帧分配(添加)一个新列-包含一个条件语句
我想根据2个现有列的值向现有dask数据帧添加一个新列,并包含一个用于检查空值的条件语句: 数据帧定义Python 基于2个现有列的值为dask数据帧分配(添加)一个新列-包含一个条件语句,python,pandas,dask,Python,Pandas,Dask,我想根据2个现有列的值向现有dask数据帧添加一个新列,并包含一个用于检查空值的条件语句: 数据帧定义 import pandas as pd import dask.dataframe as dd df = pd.DataFrame({'x': [1, 2, 3, 4, 5], 'y': [0.2, "", 0.345, 0.40, 0.15]}) ddf = dd.from_pandas(df1, npartitions=2) 尝试了方法1 def funcUpdate(row):
import pandas as pd
import dask.dataframe as dd
df = pd.DataFrame({'x': [1, 2, 3, 4, 5], 'y': [0.2, "", 0.345, 0.40, 0.15]})
ddf = dd.from_pandas(df1, npartitions=2)
尝试了方法1
def funcUpdate(row):
if row['y'].isnull():
return row['y']
else:
return round((1 + row['x'])/(1+ 1/row['y']),4)
ddf = ddf.assign(z= ddf.apply(funcUpdate, axis=1 , meta = ddf))
它给出了一个错误:
TypeError: Column assignment doesn't support type DataFrame
方法2
ddf = ddf.assign(z = ddf.apply(lambda col: col.y if col.y.isnull() else round((1 + col.x)/(1+ 1/col.y),4),axis = 1, meta = ddf))
你知道该怎么做吗 我对dask没有任何经验,但是您的布尔测试不会在funcUpdate中将第二个元素捕捉为null。带pandas的Null值等于None或NaN/NaN,而不是“”
这是一种可能的解决方法,但您需要先运行数据验证。您可以使用
fillna
(快速)或使用apply
(缓慢但灵活)
菲尔纳
当然,在这种情况下,因为函数使用了y
,如果y
为空,那么结果也将为空。我假设您不是有意的,所以我稍微更改了输出
应用
任何熊猫专家都会告诉你,使用apply
会带来10到100倍的减速惩罚。请小心
尽管如此,灵活性是有用的。您的示例几乎可以正常工作,只是您提供了不正确的元数据。您告诉apply函数生成了一个数据帧,而实际上我认为您的函数旨在生成一个系列。您可以让Dask为您猜测元信息(尽管它会抱怨),也可以显式指定数据类型。以下示例中显示了这两个选项:
In [1]: import pandas as pd
...:
...: import dask.dataframe as dd
...: df = pd.DataFrame({'x': [1, 2, 3, 4, 5], 'y': [0.2, None, 0.345, 0.40, 0.15]})
...: ddf = dd.from_pandas(df, npartitions=2)
...:
In [2]: def func(row):
...: if pd.isnull(row['y']):
...: return row['x'] + 100
...: else:
...: return row['y']
...:
In [3]: ddf['z'] = ddf.apply(func, axis=1)
/home/mrocklin/Software/anaconda/lib/python3.4/site-packages/dask/dataframe/core.py:2553: 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)
In [4]: ddf.compute()
Out[4]:
x y z
0 1 0.200 0.200
1 2 NaN 102.000
2 3 0.345 0.345
3 4 0.400 0.400
4 5 0.150 0.150
In [5]: ddf['z'] = ddf.apply(func, axis=1, meta=float)
In [6]: ddf.compute()
Out[6]:
x y z
0 1 0.200 0.200
1 2 NaN 102.000
2 3 0.345 0.345
3 4 0.400 0.400
4 5 0.150 0.150
使用
numpy.where
你是对的,我没有将y设置为null。实际上,我错误地定义了空值,这也导致了错误。谢谢你的解释,帮助很大。虽然我不确定fastna是否会有帮助,因为实际函数是这样的:def func(row):if pd.isnull(row['y']):return row['x']否则:return round((1+row['x'])/(1+1/row['y']),4)
基本上如果y为null,新的列z=x,否则,新的z列等于return语句中的计算。另一个问题是,为什么不能将isnull应用于dask数据帧的一列,使用pandas语法对我来说有点奇怪:if pd.isnull(row['y']):
在这种情况下如何应用。赋值?我使用pd.isnull(row['y'])
因为row['y']
是一个浮点数,没有pandas方法。ddf['z']=foo
相当于ddf=ddf.assign(z=foo)
对于任何foo
。我认为我的数据帧定义中的一个问题是我将Null定义为“”,其中as应该定义为“无”
import pandas as pd
import dask.dataframe as dd
df = pd.DataFrame({'x': [1, 2, 3, 4, 5], 'y': [0.2, None, 0.345, 0.40, 0.15]})
ddf = dd.from_pandas(df, npartitions=2)
ddf['z'] = ddf.y.fillna((100 + ddf.x))
>>> df
x y
0 1 0.200
1 2 NaN
2 3 0.345
3 4 0.400
4 5 0.150
>>> ddf.compute()
x y z
0 1 0.200 0.200
1 2 NaN 102.000
2 3 0.345 0.345
3 4 0.400 0.400
4 5 0.150 0.150
In [1]: import pandas as pd
...:
...: import dask.dataframe as dd
...: df = pd.DataFrame({'x': [1, 2, 3, 4, 5], 'y': [0.2, None, 0.345, 0.40, 0.15]})
...: ddf = dd.from_pandas(df, npartitions=2)
...:
In [2]: def func(row):
...: if pd.isnull(row['y']):
...: return row['x'] + 100
...: else:
...: return row['y']
...:
In [3]: ddf['z'] = ddf.apply(func, axis=1)
/home/mrocklin/Software/anaconda/lib/python3.4/site-packages/dask/dataframe/core.py:2553: 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)
In [4]: ddf.compute()
Out[4]:
x y z
0 1 0.200 0.200
1 2 NaN 102.000
2 3 0.345 0.345
3 4 0.400 0.400
4 5 0.150 0.150
In [5]: ddf['z'] = ddf.apply(func, axis=1, meta=float)
In [6]: ddf.compute()
Out[6]:
x y z
0 1 0.200 0.200
1 2 NaN 102.000
2 3 0.345 0.345
3 4 0.400 0.400
4 5 0.150 0.150