Экспорт кадра данных с нулевым Int64 из панд в R - PullRequest
1 голос
/ 26 октября 2019

Я пытаюсь экспортировать фрейм данных, который содержит среди прочих категориальные и обнуляемые целочисленные столбцы , чтобы их можно было легко прочитать по R.

Я поставил свои ставки на перо Apache, нок сожалению, тип данных Int64 от панд, по-видимому, не реализован:

from pyarrow import feather
import pandas as pd

col1 = pd.Series([0, None, 1, 23]).astype('Int64')
col2 = pd.Series([1, 3, 2, 1]).astype('Int64')

df = pd.DataFrame({'a': col1, 'b': col2})

feather.write_feather(df, '/tmp/foo')

Это сообщение об ошибке, которое появляется:

---------------------------------------------------------------------------
ArrowTypeError                            Traceback (most recent call last)
<ipython-input-107-8cc611a30355> in <module>
----> 1 feather.write_feather(df, '/tmp/foo')

~/miniconda3/envs/sci36/lib/python3.6/site-packages/pyarrow/feather.py in write_feather(df, dest)
    181     writer = FeatherWriter(dest)
    182     try:
--> 183         writer.write(df)
    184     except Exception:
    185         # Try to make sure the resource is closed

~/miniconda3/envs/sci36/lib/python3.6/site-packages/pyarrow/feather.py in write(self, df)
     92         # TODO(wesm): Remove this length check, see ARROW-1732
     93         if len(df.columns) > 0:
---> 94             table = Table.from_pandas(df, preserve_index=False)
     95             for i, name in enumerate(table.schema.names):
     96                 col = table[i]

~/miniconda3/envs/sci36/lib/python3.6/site-packages/pyarrow/table.pxi in pyarrow.lib.Table.from_pandas()

~/miniconda3/envs/sci36/lib/python3.6/site-packages/pyarrow/pandas_compat.py in dataframe_to_arrays(df, schema, preserve_index, nthreads, columns, safe)
    551     if nthreads == 1:
    552         arrays = [convert_column(c, f)
--> 553                   for c, f in zip(columns_to_convert, convert_fields)]
    554     else:
    555         from concurrent import futures

~/miniconda3/envs/sci36/lib/python3.6/site-packages/pyarrow/pandas_compat.py in <listcomp>(.0)
    551     if nthreads == 1:
    552         arrays = [convert_column(c, f)
--> 553                   for c, f in zip(columns_to_convert, convert_fields)]
    554     else:
    555         from concurrent import futures

~/miniconda3/envs/sci36/lib/python3.6/site-packages/pyarrow/pandas_compat.py in convert_column(col, field)
    542             e.args += ("Conversion failed for column {0!s} with type {1!s}"
    543                        .format(col.name, col.dtype),)
--> 544             raise e
    545         if not field_nullable and result.null_count > 0:
    546             raise ValueError("Field {} was non-nullable but pandas column "

~/miniconda3/envs/sci36/lib/python3.6/site-packages/pyarrow/pandas_compat.py in convert_column(col, field)
    536 
    537         try:
--> 538             result = pa.array(col, type=type_, from_pandas=True, safe=safe)
    539         except (pa.ArrowInvalid,
    540                 pa.ArrowNotImplementedError,

ArrowTypeError: ('Did not pass numpy.dtype object', 'Conversion failed for column a with type Int64')

Есть ли обходной путь, который позволяет мне использоватьэтот специальный тип данных Int64, предпочтительно с использованием пиарроу?

1 Ответ

2 голосов
/ 28 октября 2019

В последнем выпуске Arrow (pyarrow 0.15.0) и при использовании версии разработки для pandas теперь поддерживается:

In [1]: from pyarrow import feather 
   ...: import pandas as pd 
   ...:  
   ...: col1 = pd.Series([0, None, 1, 23]).astype('Int64') 
   ...: col2 = pd.Series([1, 3, 2, 1]).astype('Int64') 
   ...:  
   ...: df = pd.DataFrame({'a': col1, 'b': col2}) 
   ...:  
   ...: feather.write_feather(df, '/tmp/foo') 

In [2]: feather.read_table('/tmp/foo')
Out[2]: 
pyarrow.Table
a: int64
b: int64

Вы можете видеть, что полученная таблица стрелок (при чтении обратно)правильно имеет целочисленные столбцы. Таким образом, чтобы получить это в выпущенной версии, он ждет, пока панды 1.0.

На данный момент (без использования мастера панд) у вас есть два варианта обхода:

  • Преобразование столбца в столбец типа d объекта (df['a'] = df['a'].astype(object)), а затем записьпероДля этих столбцов объекта (с целыми числами и пропущенными значениями) Pyarrow правильно выведет, что это целые числа.

  • Панды Monkeypatch на данный момент (до следующего выпуска панд):

    pd.arrays.IntegerArray.__arrow_array__ = lambda self, type: pyarrow.array(self._data, mask=self._mask, type=type)
    

    При этом написание целочисленных столбцов, содержащих пустые целые числа, с пиарроу / пером должно работать из коробки (для этого вам все еще нужен последний пиарроу 0,15,0).


Примечаниечто чтение файла пера обратно в pandas DataFrame пока еще приведет к появлению столбца с плавающей запятой (если отсутствуют значения), так как это преобразование целого числа стрелки в pandas по умолчанию. Продолжается работа по сохранению этих конкретных типов панд при преобразовании в панд (см. https://issues.apache.org/jira/browse/ARROW-2428).

...