Python 达斯克+;熊猫:返回一系列条件假人

Python 达斯克+;熊猫:返回一系列条件假人,python,pandas,dask,dummy-variable,bigdata,Python,Pandas,Dask,Dummy Variable,Bigdata,在Pandas中,如果我想创建一列条件虚拟对象(例如,如果变量等于字符串,则为1;如果变量不等于字符串,则为0),那么我在Pandas中的goto是: data["ebt_dummy"] = np.where((data["paymenttypeid"]=='ebt'), 1, 0) 在dask数据帧中天真地尝试此操作会抛出错误。遵循map_分区文档中的说明也会引发错误: data = data.map_partitions(lambda df: df.assign(ebt_dummy = n

在Pandas中,如果我想创建一列条件虚拟对象(例如,如果变量等于字符串,则为1;如果变量不等于字符串,则为0),那么我在Pandas中的goto是:

data["ebt_dummy"] = np.where((data["paymenttypeid"]=='ebt'), 1, 0)
在dask数据帧中天真地尝试此操作会抛出错误。遵循map_分区文档中的说明也会引发错误:

data = data.map_partitions(lambda df: df.assign(ebt_dummy = np.where((df["paymenttypeid"]=='ebt'), 1, 0)),  meta={'paymenttypeid': 'str', 'ebt_dummy': 'i8'})

做这件事的好方法是什么,或者说最简单的方法是什么

以下是一些示例数据:

In [1]:
df = pd.DataFrame(np.transpose([np.random.choice(['ebt','other'], (10)),
              np.random.rand(10)]), columns=['paymenttypeid','other'])

df

Out[1]:

  paymenttypeid                 other
0         other    0.3130770966143612
1         other    0.5167434068096931
2           ebt    0.7606898392115471
3           ebt    0.9424572692382547
4           ebt     0.624282017575857
5           ebt    0.8584841824784487
6         other    0.5017083765654611
7         other  0.025994123211164233
8           ebt   0.07045354449612984
9           ebt   0.11976351556850084
让我们将其转换为数据帧

In [2]: data = dd.from_pandas(df, npartitions=2)
并使用
apply
(在序列上)分配:

In [3]:
data['ebt_dummy'] = data.paymenttypeid.apply(lambda x: 1 if x =='ebt' else 0, meta=('paymenttypeid', 'str'))
data.compute()

Out [3]:
  paymenttypeid                 other  ebt_dummy
0         other    0.3130770966143612          0
1         other    0.5167434068096931          0
2           ebt    0.7606898392115471          1
3           ebt    0.9424572692382547          1
4           ebt     0.624282017575857          1
5           ebt    0.8584841824784487          1
6         other    0.5017083765654611          0
7         other  0.025994123211164233          0
8           ebt   0.07045354449612984          1
9           ebt   0.11976351556850084          1

更新:

您传递的
meta
似乎是一个问题,因为这是有效的:

data = data.map_partitions(lambda df: df.assign(
                                    ebt_dummy = np.where((df["paymenttypeid"]=='ebt'), 1, 0)))

data.compute()
在我的示例中,如果我想指定
,我必须传递当前
数据
的数据类型,而不是分配后我期望的类型:

data.map_partitions(lambda df: df.assign(
                                    ebt_dummy = np.where((df["paymenttypeid"]=='ebt'), 1, 0)), 
               meta={'paymenttypeid': 'str', 'other': 'float64'})

这也对我起了作用:

data['ebt_dummy'] = dd.from_array(np.where((df["paymenttypeid"]=='ebt'), 1, 0))

谢谢你的回答!有没有矢量化的方法可以做到这一点?我已经想到了这一点,但是在一个小数据集之外的任何东西上进行逐行应用是非常禁止的。我更新了我的答案,用
map\u分区进行应用(直到现在才使用Dask…)。我建议你修改你的
meta
关键字。上面的方法很好。是的,就是这样。我误解了元。谢谢你的帮助!对于将来偶然发现这一点的人来说,这只是最后的补充。奇怪的是,与我的第一个批评正好相反,逐行应用似乎比矢量化方法更快,使用更少的ram,至少在我的数据测试中是这样。这一定是dask的一个奇怪的怪癖(或者它可能与必须减少数据的总拷贝数有关),我认为这将取决于几个关键因素,包括您的数据有多大,您有什么硬件(如果您想要几十个具有大数据的核,它可能更具成本效益),以及您如何配置dask。另外,如果在调用compute之前执行多个操作,显然也会更好。