Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于2个现有列的值为dask数据帧分配(添加)一个新列-包含一个条件语句_Python_Pandas_Dask - Fatal编程技术网

Python 基于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):

我想根据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):
    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