mirror of
https://github.com/apache/arrow.git
synced 2026-10-28 16:47:19 +08:00
266 lines
6.1 KiB
Cython
266 lines
6.1 KiB
Cython
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
# cython: profile=False
|
|
# distutils: language = c++
|
|
# cython: embedsignature = True
|
|
|
|
import numpy as np
|
|
|
|
from pyarrow.includes.libarrow cimport *
|
|
cimport pyarrow.includes.pyarrow as pyarrow
|
|
|
|
import pyarrow.config
|
|
|
|
from pyarrow.compat import frombytes, tobytes
|
|
from pyarrow.error cimport check_status
|
|
|
|
cimport pyarrow.scalar as scalar
|
|
from pyarrow.scalar import NA
|
|
|
|
from pyarrow.schema cimport Schema
|
|
import pyarrow.schema as schema
|
|
|
|
|
|
def total_allocated_bytes():
|
|
cdef MemoryPool* pool = pyarrow.get_memory_pool()
|
|
|
|
|
|
cdef class Array:
|
|
|
|
cdef init(self, const shared_ptr[CArray]& sp_array):
|
|
self.sp_array = sp_array
|
|
self.ap = sp_array.get()
|
|
self.type = DataType()
|
|
self.type.init(self.sp_array.get().type())
|
|
|
|
@staticmethod
|
|
def from_pandas(obj, mask=None):
|
|
return from_pandas_series(obj, mask)
|
|
|
|
property null_count:
|
|
|
|
def __get__(self):
|
|
return self.sp_array.get().null_count()
|
|
|
|
def __iter__(self):
|
|
for i in range(len(self)):
|
|
yield self.getitem(i)
|
|
raise StopIteration
|
|
|
|
def __repr__(self):
|
|
from pyarrow.formatting import array_format
|
|
type_format = object.__repr__(self)
|
|
values = array_format(self, window=10)
|
|
return '{0}\n{1}'.format(type_format, values)
|
|
|
|
def equals(Array self, Array other):
|
|
return self.ap.Equals(other.sp_array)
|
|
|
|
def __len__(self):
|
|
if self.sp_array.get():
|
|
return self.sp_array.get().length()
|
|
else:
|
|
return 0
|
|
|
|
def isnull(self):
|
|
raise NotImplemented
|
|
|
|
def __getitem__(self, key):
|
|
cdef:
|
|
Py_ssize_t n = len(self)
|
|
|
|
if PySlice_Check(key):
|
|
start = key.start or 0
|
|
while start < 0:
|
|
start += n
|
|
|
|
stop = key.stop if key.stop is not None else n
|
|
while stop < 0:
|
|
stop += n
|
|
|
|
step = key.step or 1
|
|
if step != 1:
|
|
raise NotImplementedError
|
|
else:
|
|
return self.slice(start, stop)
|
|
|
|
while key < 0:
|
|
key += len(self)
|
|
|
|
return self.getitem(key)
|
|
|
|
cdef getitem(self, int i):
|
|
return scalar.box_arrow_scalar(self.type, self.sp_array, i)
|
|
|
|
def slice(self, start, end):
|
|
pass
|
|
|
|
|
|
cdef class NullArray(Array):
|
|
pass
|
|
|
|
|
|
cdef class BooleanArray(Array):
|
|
pass
|
|
|
|
|
|
cdef class NumericArray(Array):
|
|
pass
|
|
|
|
|
|
cdef class Int8Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class UInt8Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class Int16Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class UInt16Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class Int32Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class UInt32Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class Int64Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class UInt64Array(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class FloatArray(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class DoubleArray(NumericArray):
|
|
pass
|
|
|
|
|
|
cdef class ListArray(Array):
|
|
pass
|
|
|
|
|
|
cdef class StringArray(Array):
|
|
pass
|
|
|
|
|
|
cdef dict _array_classes = {
|
|
Type_NA: NullArray,
|
|
Type_BOOL: BooleanArray,
|
|
Type_UINT8: UInt8Array,
|
|
Type_UINT16: UInt16Array,
|
|
Type_UINT32: UInt32Array,
|
|
Type_UINT64: UInt64Array,
|
|
Type_INT8: Int8Array,
|
|
Type_INT16: Int16Array,
|
|
Type_INT32: Int32Array,
|
|
Type_INT64: Int64Array,
|
|
Type_FLOAT: FloatArray,
|
|
Type_DOUBLE: DoubleArray,
|
|
Type_LIST: ListArray,
|
|
Type_STRING: StringArray,
|
|
Type_TIMESTAMP: Int64Array,
|
|
}
|
|
|
|
cdef object box_arrow_array(const shared_ptr[CArray]& sp_array):
|
|
if sp_array.get() == NULL:
|
|
raise ValueError('Array was NULL')
|
|
|
|
cdef CDataType* data_type = sp_array.get().type().get()
|
|
|
|
if data_type == NULL:
|
|
raise ValueError('Array data type was NULL')
|
|
|
|
cdef Array arr = _array_classes[data_type.type]()
|
|
arr.init(sp_array)
|
|
return arr
|
|
|
|
|
|
def from_pylist(object list_obj, DataType type=None):
|
|
"""
|
|
Convert Python list to Arrow array
|
|
"""
|
|
cdef:
|
|
shared_ptr[CArray] sp_array
|
|
|
|
if type is None:
|
|
check_status(pyarrow.ConvertPySequence(list_obj, &sp_array))
|
|
else:
|
|
raise NotImplementedError
|
|
|
|
return box_arrow_array(sp_array)
|
|
|
|
|
|
def from_pandas_series(object series, object mask=None, timestamps_to_ms=False):
|
|
"""
|
|
Convert pandas.Series to an Arrow Array.
|
|
|
|
Parameters
|
|
----------
|
|
series: pandas.Series or numpy.ndarray
|
|
|
|
mask: pandas.Series or numpy.ndarray
|
|
array to mask null entries in the series
|
|
|
|
timestamps_to_ms: bool
|
|
Convert datetime columns to ms resolution. This is needed for
|
|
compability with other functionality like Parquet I/O which
|
|
only supports milliseconds.
|
|
"""
|
|
cdef:
|
|
shared_ptr[CArray] out
|
|
|
|
series_values = series_as_ndarray(series)
|
|
if series_values.dtype.type == np.datetime64 and timestamps_to_ms:
|
|
series_values = series_values.astype('datetime64[ms]')
|
|
|
|
if mask is None:
|
|
with nogil:
|
|
check_status(pyarrow.PandasToArrow(pyarrow.get_memory_pool(),
|
|
series_values, &out))
|
|
else:
|
|
mask = series_as_ndarray(mask)
|
|
with nogil:
|
|
check_status(pyarrow.PandasMaskedToArrow(
|
|
pyarrow.get_memory_pool(), series_values, mask, &out))
|
|
|
|
return box_arrow_array(out)
|
|
|
|
|
|
cdef object series_as_ndarray(object obj):
|
|
import pandas as pd
|
|
|
|
if isinstance(obj, pd.Series):
|
|
result = obj.values
|
|
else:
|
|
result = obj
|
|
|
|
return result
|