Размер буфера должен делиться на размер элемента при преобразовании pandas фрейма данных в фрейм cudf - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть фрейм данных со столбцом в виде значений, разделенных запятыми, с кавычками ie., Строковый объект. Пример:

  df['a']
'1,2,3,4,5'
'2,3,4,5,6'

Я могу преобразовать список значений в формате строки в массив NumPy и могу успешно выполнить свою операцию.

def func(x):
    return something

for t_df in pd.read_csv("testset.csv",chunksize=2000):
    t_df['predicted'] = t_df['prev'].parallel_apply(lambda x : arima(ast.literal_eval(x),1))

До сих пор у меня нет ' т любой вопрос. Но fun c работает с моделями прогнозирования, что требует довольно много времени, а размер кадра данных составляет 2 миллиона записей.

Итак, я попробовал пакет cudf в python для использования функциональности графического процессора. на Pandas как кадры данных. Здесь возникает проблема

for t_df in pd.read_csv("testset.csv",chunksize=2):
    t_df['prev'] = t_df['prev'].apply(lambda x : np.array(ast.literal_eval(x)))
    t_df = cudf.DataFrame.from_pandas(t_df)

Когда я применяю ту же операцию, происходит сбой с ошибкой, которая в основном не может преобразовать строковый объект в массив NumPy. Ошибка выглядит следующим образом

> ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-19-e7866d751352> in <module>
     12     t_df['prev'] = t_df['prev'].apply(lambda x : np.array(ast.literal_eval(x)))
     13     st = time.time()
---> 14     t_df = cudf.DataFrame.from_pandas(t_df)
     15     t_df['predicted'] = 10
     16     res.append(t_df)

/opt/conda/lib/python3.7/site-packages/cudf/core/dataframe.py in from_pandas(cls, dataframe, nan_as_null)
   3109             # columns for a single key
   3110             if len(vals.shape) == 1:
-> 3111                 df[i] = Series(vals, nan_as_null=nan_as_null)
   3112             else:
   3113                 vals = vals.T

/opt/conda/lib/python3.7/site-packages/cudf/core/series.py in __init__(self, data, index, name, nan_as_null, dtype)
    128 
    129         if not isinstance(data, column.ColumnBase):
--> 130             data = column.as_column(data, nan_as_null=nan_as_null, dtype=dtype)
    131 
    132         if index is not None and not isinstance(index, Index):

/opt/conda/lib/python3.7/site-packages/cudf/core/column/column.py in as_column(arbitrary, nan_as_null, dtype, length)
   1353         elif arb_dtype.kind in ("O", "U"):
   1354             data = as_column(
-> 1355                 pa.Array.from_pandas(arbitrary), dtype=arbitrary.dtype
   1356             )
   1357         else:

/opt/conda/lib/python3.7/site-packages/cudf/core/column/column.py in as_column(arbitrary, nan_as_null, dtype, length)
   1265                 mask=pamask,
   1266                 size=pa_size,
-> 1267                 offset=pa_offset,
   1268             )
   1269 

/opt/conda/lib/python3.7/site-packages/cudf/core/column/numerical.py in __init__(self, data, dtype, mask, size, offset)
     30         dtype = np.dtype(dtype)
     31         if data.size % dtype.itemsize:
---> 32             raise ValueError("Buffer size must be divisible by element size")
     33         if size is None:
     34             size = data.size // dtype.itemsize

ValueError: Buffer size must be divisible by element size

Какое может быть возможное решение?

1 Ответ

0 голосов
/ 29 апреля 2020

Как и в вашем другом вопросе, я полагаю, что вы пытаетесь заставить cudf сделать что-то, что вам на самом деле не следует. Хотя RAPIDS стремится к знакомству с API, кажется, что:

  1. В настоящее время вы не используете лучшие практики cudf или cuml. Хотя ваши намерения жизнеспособны, вы не используете лучшие практики для достижения sh вашей цели, для которой у нас действительно есть ресурсы.
  2. Хотя RAPIDS может прочитать то, что находится в вашем CSV, ваша предварительная обработка пытается sh массив np.array в один столбец, и cudf не может прочитать этот формат (что приводит к вашей ошибке). Вам нужно изменить вывод на что-то, что RAPIDS может читать, например, создать столбцы для каждого элемента в этом массиве (код ниже). Это может быть пробел между pandas и RAPIDS, который вы нажали, и мы рекомендуем вам сделать запрос на добавление.

Если вы еще этого не сделали, я бы посоветовал вам go через некоторые из наших документов и примеры ноутбуков в cuml и cudf на github . У нас есть пример ноутбука arima, работающий на графическом процессоре . Они довольно быстро читаются и действительно помогут вам в этом. cudf может обрабатывать строки с помощью .str, но наш apply пока плохо работает со строками. Если ваша память GPU слишком мала, чтобы вместить все данные, используйте dask-cudf.

Самая хитрая часть здесь - это чтение набора данных, в котором строковые элементы разделены запятыми в ваших CSV. Вы хотите, чтобы каждый элемент находился в отдельном столбце вдоль строки, а не в массиве. RAPIDS applys пока плохо работает со строками, но то, что вы хотите сделать sh, очень похоже на приведенный ниже пример кода. К сожалению, RAPIDS может занять больше, чем Pandas на этом. Тем не менее, код работает как для cudf, так и для pandas, и его выходные данные более удобны для использования в экосистеме RAPIDS. Теперь, когда вы превратили свои векторы в столбцы, посмотрите, куда это приведет вас с помощью ARIMA cuml (ссылка выше).

import cudf
df = cudf.read_csv('testset.csv') 
vecnum_cols = ['a'] 
df_vecnum = cudf.DataFrame(index=df.index)

if len(vecnum_cols) >0:
    for vec in vecnum_cols:
        v = df[vec].str.split(",", expand = True).reset_index(drop=True)
        v.columns  = [ vec + '_' + str(i) for i in range(v.shape[1])]
        #print(len(v.columns))
        df_vecnum = df_vecnum.join(v) 
print(df_vecnum.head())

Надеюсь, это все поможет. Я не могу гарантировать вам, что он доставит вас туда, куда вы хотите go, но исходя из того, что я видел выше, он должен направить вас в правильном направлении.

...