如何插入numpy ndarray切片作为新的Dask DataFrame列?

时间:2019-06-28 19:25:21

标签: python dask numpy-ndarray numpy-slicing

我正在尝试使用代码(在下面的链接中提供)将纬度/经度坐标映射到纽约市自治市镇:

https://www.kaggle.com/muonneutrino/nyc-taxis-eda-and-mapping-position-to-borough

我正在低内存的本地Jupyter环境中工作,因此我已将带有出租车经/纬度数据的.csv大文件导入了一个昏暗的数据框。

首先,我使用发现的here的2016年6月黄色出租车数据来创建一个简单的数据框: 并将其设为test_day的子集,以使集合变小:

import pandas as pd
import dask.dataframe as dd
import dask.array as da

from dask.distributed import Client
client = Client(processes=False)
%pylab inline

cols= ['pickup_longitude', 'pickup_latitude', 'tpep_pickup_datetime',]
ddf = dd.read_csv('yellow_tripdata_2016-06.csv',blocksize=13e7,assume_missing=True, usecols=cols)
ddf['tpep_pickup_datetime'] = dd.to_datetime(ddf.tpep_pickup_datetime, errors='ignore')
ddf['pickup_day'] = ddf.tpep_pickup_datetime.dt.day
td = ddf.loc[ddf.pickup_day == 10]
td = td.rename(columns={'pickup_longitude':'plon',
                    'pickup_latitude':'plat'} )

我首先声明值latmin,lonmin,latmax和lonmax并创建numpy数组map_tracts:

xmin = 40.48
ymin = -74.28
xmax = 40.93
ymax = -73.65
dlat = (xmax-xmin) / 199
dlon = (ymax-ymin) / 199
td['lat_idx'] = (np.rint((td['plat'] - latmin) / dlat))
td['lon_idx'] = (np.rint((td['plon'] - lonmin) / dlon ))  
map_tracts = ([[34023007600, 34023007600, 34023007500, 34031246300,
        34031246300, 34031246300],
       [34023007600, 34023007600, 34023007600, 34031246300,
        34031246300, 34031246300],
       [34023007600, 34023007600, 34023007600, 34031246300,
        34031246300, 34031246300],
       [          0,           0,           0, 36059990200,
        36119007600, 36119007600],
       [          0,           0,           0, 36059990200,
        36059990200, 36119007600]])

然后我尝试运行一个dask数组where子句:

td['pu_tracts'] = da.where(((xmin < td.plat < xmax) & 
                            (ymin < td.plong < ymin)),
                            (map_tracts[td.lat_idx, td.lon_idx]),0)

但是收到一个错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-24-5228e3ec653a> in <module>
----> 1 td['pu_tracts'] = np.where(((xmin < td.plat < xmax) & 
      2                                  (ymin < td.plong < ymin)),
      3                                  (map_tracts[td_day.lat_idx, td.lon_idx]),0)

~/anaconda3/lib/python3.7/site-packages/dask/dataframe/core.py in __bool__(self)
    441         raise ValueError("The truth value of a {0} is ambiguous. "
    442                          "Use a.any() or a.all()."
--> 443                          .format(self.__class__.__name__))
    444 
    445     __nonzero__ = __bool__  # python 2

ValueError: The truth value of a Series is ambiguous. Use a.any() or a.all().

这是一个愚蠢的问题吗?

1 个答案:

答案 0 :(得分:1)

更新:经过OP的代码和MCVE的反复研究后,发现map_tracts[lon_idx,lat_idx]甚至不是函数,而是dask.DataFramenp.ndarray(OP :是什么?!请只给我们看type(map_tracts[lon_idx,lat_idx])。)

UPDATE2:map_tracts[lon_idx,lat_idx]甚至都不是dask.DataFrame/Series,它是通过切片为map_tracts(一个numpy.ndarray)而获得的单个(numpy)值,然后OP构建了一个np .ndarray从这些列表的理解。

如果要将numpy数组返回到dask DataFrame,则可能需要将其包装为包含单个序列的另一个dask.DataFrame(请参阅dask文档)。


我没有使用过dask,但是有一个例外的快速Google在github上找到了以下dask已知问题(已关闭,不会修复):

#4429: Join dask.DataFrame with dask.Series “有人可以让我知道如何将一个dask数据框与一个dask系列对象结合起来。”

已通过建议 “尝试to_frame方法” 关闭(大概是修复)。

您的函数get_tract依次调用您未提供代码的{​​{1}}(这是第三方库吗?numpy调用?您自己的某些代码未显示?)至关重要的是,我们无法看到其返回类型是否为map_tractsdask.Seriesdask.DataFramenumpy.ndarray,基本Python列表等。这很重要。

解决方案:假设pandas.Series返回一个map_tracts(),您可能需要通过调用dask.Series

对其进行包装

他们永远不会修复这些问题,甚至不让它们开放以供将来版本考虑的模糊态度听起来很弱,您应该对此问题发表评论,尝试重新打开(包括此SO问题的链接),以及我建议还对他们打开一个dask docbug,至少他们的文档需要显示如何正确执行代码示例;合并列是相当基本的事情。

(坦白地说,Databricks recently (4/2019) launched koalas as a drop-in Spark replacement for pandas,所以我希望一部分对性能至关重要的Python / pandas用户改用dask可能会迁移到Spark /考拉。)