Как вставить кусочек ndarray как новый столбец Dask DataFrame? - PullRequest
0 голосов
/ 28 июня 2019

Я пытаюсь использовать код (предоставленный по ссылке ниже), чтобы сопоставить координаты широты и долготы с районами Нью-Йорка:

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

Я работаю с нехваткой памятилокальная среда Jupyter, поэтому я импортировал большой файл .csv с данными Taxi lat / long в фрейм данных dask.

Сначала я создаю фрейм данных dask с найденными данными Yellow Cab за июнь 2016 года здесь : и подмножество 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, где предложение:

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().

Это проблема с dask?

1 Ответ

1 голос
/ 28 июня 2019

ОБНОВЛЕНИЕ: после долгих перерывов в коде OP и MCVE получается, что map_tracts[lon_idx,lat_idx] даже не функция, а либо dask.DataFrame, либо, может быть, np.ndarray (ОП: что это ?!Просто покажите нам type(map_tracts[lon_idx,lat_idx]), пожалуйста, пожалуйста.)

ОБНОВЛЕНИЕ2: map_tracts[lon_idx,lat_idx] тоже даже не dask.DataFrame/Series, это единственное (numpy) значение, полученное путем нарезки на map_tracts (numpy.ndarray)), а затем OP создает массив np.ndarray из списка, представляющего их.

Если вы хотите вернуть массив данных numy в dask DataFrame, вам может понадобиться обернуть его как другой dask.DataFrame (см. daskдокумент для этого), содержащий одну серию.


Я не использовал dask, но быстрый Google за вашим исключением находит следующую известную проблему dask на github (закрыто, wont-fix):

# 4429: Присоединиться к dask.DataFrame с помощью dask.Series "Может кто-нибудь сообщить мне, как соединить кадр данных dask с объектом серии dask."

, который был закрыт (wont-fix, предположительно) с рекомендацией "Попробуйте to_frame method ".

Ваша функция get_tract в свою очередь вызывает map_tracts, для которого вы не дали код (это сторонняя библиотека?тупой звонок?какой-то ваш собственный код, который вы не показали?) И, что важно, мы не можем видеть, имеет ли его тип возвращаемого значения dask.Series, dask.DataFrame, numpy.ndarray, pandas.Series, базовый список Python и т. д. Это важно.

Решение: предполагая, что map_tracts() возвращает dask.Series, вам, вероятно, нужно обернуть его, позвонив по номеру dask.Series._to_frame()

Пьяная позиция, что они никогда не исправят это идаже не оставлять их открытыми для рассмотрения в будущих версиях, звучит довольно слабо, и вы должны оставить комментарий по этому вопросу, попытаться открыть его снова (включить ссылку на этот вопрос), и я предлагаю также открыть dask docbug на них, как минимум, их документнеобходимо показать пример кода, как это сделать правильно;объединение столбцов - довольно простая вещь.

(Если честно, Недавно Databricks (4/2019) запустил koalas как замену Spark для панд , поэтому я ожидаюПодмножество критичных к производительности пользователей Python / pandas, которые переключились на dask, могут перейти на Spark / koalas.)

...