Add datetime.date conversions

Change-Id: I6627e7be236b669600301ff6f073d79cef0f3ed0
This commit is contained in:
Uwe L. Korn committed 2016-12-16 17:30:54 +01:00
1 parent 6fca4da8aa
commit 6bf346f105
11 files changed
+91 -2

No files matched your search

+4
View File
@@ -88,6 +88,10 @@ std::string StructType::ToString() const {
return s.str();
}
std::string DateType::ToString() const {
return std::string("date");
}
std::string UnionType::ToString() const {
std::stringstream s;
+1 -1
View File
@@ -420,7 +420,7 @@ struct ARROW_EXPORT DateType : public FixedWidthType {
int bit_width() const override { return sizeof(c_type) * 8; }
Status Accept(TypeVisitor* visitor) const override;
std::string ToString() const override { return name(); }
std::string ToString() const override;
static std::string name() { return "date"; }
};
+1
View File
@@ -45,6 +45,7 @@ from pyarrow.scalar import (ArrayValue, Scalar, NA, NAType,
from pyarrow.schema import (null, bool_,
int8, int16, int32, int64,
uint8, uint16, uint32, uint64,
timestamp, date,
float_, double, string,
list_, struct, field,
DataType, Field, Schema, schema)
+6 -1
View File
@@ -212,6 +212,10 @@ cdef class UInt64Array(NumericArray):
pass
cdef class DateArray(NumericArray):
pass
cdef class FloatArray(NumericArray):
pass
@@ -239,6 +243,7 @@ cdef dict _array_classes = {
Type_INT16: Int16Array,
Type_INT32: Int32Array,
Type_INT64: Int64Array,
Type_DATE: DateArray,
Type_FLOAT: FloatArray,
Type_DOUBLE: DoubleArray,
Type_LIST: ListArray,
@@ -278,7 +283,7 @@ def from_pylist(object list_obj, DataType type=None):
if type is None:
check_status(pyarrow.ConvertPySequence(list_obj, &sp_array))
else:
raise NotImplementedError
raise NotImplementedError()
return box_arrow_array(sp_array)
+4
View File
@@ -39,6 +39,7 @@ cdef extern from "arrow/api.h" namespace "arrow" nogil:
Type_DOUBLE" arrow::Type::DOUBLE"
Type_TIMESTAMP" arrow::Type::TIMESTAMP"
Type_DATE" arrow::Type::DATE"
Type_STRING" arrow::Type::STRING"
Type_LIST" arrow::Type::LIST"
@@ -132,6 +133,9 @@ cdef extern from "arrow/api.h" namespace "arrow" nogil:
cdef cppclass CInt64Array" arrow::Int64Array"(CArray):
int64_t Value(int i)
cdef cppclass CDateArray" arrow::DateArray"(CArray):
int64_t Value(int i)
cdef cppclass CFloatArray" arrow::FloatArray"(CArray):
float Value(int i)
+11
View File
@@ -20,6 +20,9 @@ from pyarrow.schema cimport DataType, box_data_type
from pyarrow.compat import frombytes
import pyarrow.schema as schema
import datetime
NA = None
cdef class NAType(Scalar):
@@ -120,6 +123,13 @@ cdef class UInt64Value(ArrayValue):
return ap.Value(self.index)
cdef class DateValue(ArrayValue):
def as_py(self):
cdef CDateArray* ap = <CDateArray*> self.sp_array.get()
return datetime.date.fromtimestamp(ap.Value(self.index) / 1000)
cdef class FloatValue(ArrayValue):
def as_py(self):
@@ -184,6 +194,7 @@ cdef dict _scalar_classes = {
Type_INT16: Int16Value,
Type_INT32: Int32Value,
Type_INT64: Int64Value,
Type_DATE: DateValue,
Type_FLOAT: FloatValue,
Type_DOUBLE: DoubleValue,
Type_LIST: ListValue,
+7
View File
@@ -164,6 +164,7 @@ cdef set PRIMITIVE_TYPES = set([
Type_UINT16, Type_INT16,
Type_UINT32, Type_INT32,
Type_UINT64, Type_INT64,
Type_TIMESTAMP, Type_DATE,
Type_FLOAT, Type_DOUBLE])
def null():
@@ -196,6 +197,12 @@ def uint64():
def int64():
return primitive_type(Type_INT64)
def timestamp():
return primitive_type(Type_TIMESTAMP)
def date():
return primitive_type(Type_DATE)
def float_():
return primitive_type(Type_FLOAT)
@@ -18,6 +18,7 @@
from pyarrow.compat import unittest
import pyarrow
import datetime
class TestConvertList(unittest.TestCase):
@@ -70,6 +71,17 @@ class TestConvertList(unittest.TestCase):
assert arr.null_count == 1
assert arr.type == pyarrow.string()
def test_date(self):
data = [datetime.date(2000, 1, 1), None, datetime.date(1970, 1, 1), datetime.date(2040, 2, 26)]
arr = pyarrow.from_pylist(data)
assert len(arr) == 4
assert arr.type == pyarrow.date()
assert arr.null_count == 1
assert arr[0].as_py() == datetime.date(2000, 1, 1)
assert arr[1].as_py() is None
assert arr[2].as_py() == datetime.date(1970, 1, 1)
assert arr[3].as_py() == datetime.date(2040, 2, 26)
def test_mixed_nesting_levels(self):
pyarrow.from_pylist([1, 2, None])
pyarrow.from_pylist([[1], [2], None])
+39
View File
@@ -16,6 +16,7 @@
// under the License.
#include <Python.h>
#include <datetime.h>
#include <sstream>
#include "pyarrow/adapters/builtin.h"
@@ -55,6 +56,7 @@ class ScalarVisitor {
none_count_(0),
bool_count_(0),
int_count_(0),
date_count_(0),
float_count_(0),
string_count_(0) {}
@@ -68,6 +70,8 @@ class ScalarVisitor {
++float_count_;
} else if (IsPyInteger(obj)) {
++int_count_;
} else if (PyDate_Check(obj)) {
++date_count_;
} else if (IsPyBaseString(obj)) {
++string_count_;
} else {
@@ -82,6 +86,8 @@ class ScalarVisitor {
} else if (int_count_) {
// TODO(wesm): tighter type later
return INT64;
} else if (date_count_) {
return DATE;
} else if (bool_count_) {
return BOOL;
} else if (string_count_) {
@@ -100,6 +106,7 @@ class ScalarVisitor {
int64_t none_count_;
int64_t bool_count_;
int64_t int_count_;
int64_t date_count_;
int64_t float_count_;
int64_t string_count_;
@@ -297,6 +304,35 @@ class Int64Converter : public TypedConverter<arrow::Int64Builder> {
}
};
class DateConverter : public TypedConverter<arrow::DateBuilder> {
public:
Status AppendData(PyObject* seq) override {
int64_t val;
Py_ssize_t size = PySequence_Size(seq);
RETURN_NOT_OK(typed_builder_->Reserve(size));
for (int64_t i = 0; i < size; ++i) {
OwnedRef item(PySequence_GetItem(seq, i));
if (item.obj() == Py_None) {
typed_builder_->AppendNull();
} else {
PyDateTime_Date* pydate = reinterpret_cast<PyDateTime_Date*>(item.obj());
struct tm date = {0};
date.tm_year = PyDateTime_GET_YEAR(pydate) - 1900;
date.tm_mon = PyDateTime_GET_MONTH(pydate) - 1;
date.tm_mday = PyDateTime_GET_DAY(pydate);
RETURN_IF_PYERROR();
struct tm epoch = {0};
epoch.tm_year = 70;
epoch.tm_mday = 1;
// Milliseconds since the epoch
int64_t val = lrint(difftime(mktime(&date), mktime(&epoch)) * 1000);
typed_builder_->Append(val);
}
}
return Status::OK();
}
};
class DoubleConverter : public TypedConverter<arrow::DoubleBuilder> {
public:
Status AppendData(PyObject* seq) override {
@@ -379,6 +415,8 @@ std::shared_ptr<SeqConverter> GetConverter(const std::shared_ptr<DataType>& type
return std::make_shared<BoolConverter>();
case Type::INT64:
return std::make_shared<Int64Converter>();
case Type::DATE:
return std::make_shared<DateConverter>();
case Type::DOUBLE:
return std::make_shared<DoubleConverter>();
case Type::STRING:
@@ -409,6 +447,7 @@ Status ListConverter::Init(const std::shared_ptr<ArrayBuilder>& builder) {
Status ConvertPySequence(PyObject* obj, std::shared_ptr<arrow::Array>* out) {
std::shared_ptr<DataType> type;
int64_t size;
PyDateTime_IMPORT;
RETURN_NOT_OK(InferArrowType(obj, &size, &type));
// Handle NA / NullType case
+4
View File
@@ -33,6 +33,8 @@ const std::shared_ptr<Int8Type> INT8 = std::make_shared<Int8Type>();
const std::shared_ptr<Int16Type> INT16 = std::make_shared<Int16Type>();
const std::shared_ptr<Int32Type> INT32 = std::make_shared<Int32Type>();
const std::shared_ptr<Int64Type> INT64 = std::make_shared<Int64Type>();
const std::shared_ptr<DateType> DATE = std::make_shared<DateType>();
const std::shared_ptr<TimestampType> TIMESTAMP = std::make_shared<TimestampType>();
const std::shared_ptr<FloatType> FLOAT = std::make_shared<FloatType>();
const std::shared_ptr<DoubleType> DOUBLE = std::make_shared<DoubleType>();
const std::shared_ptr<StringType> STRING = std::make_shared<StringType>();
@@ -54,6 +56,8 @@ std::shared_ptr<DataType> GetPrimitiveType(Type::type type) {
GET_PRIMITIVE_TYPE(INT32, Int32Type);
GET_PRIMITIVE_TYPE(UINT64, UInt64Type);
GET_PRIMITIVE_TYPE(INT64, Int64Type);
GET_PRIMITIVE_TYPE(DATE, DateType);
GET_PRIMITIVE_TYPE(TIMESTAMP, TimestampType);
GET_PRIMITIVE_TYPE(BOOL, BooleanType);
GET_PRIMITIVE_TYPE(FLOAT, FloatType);
GET_PRIMITIVE_TYPE(DOUBLE, DoubleType);
+2
View File
@@ -38,6 +38,8 @@ extern const std::shared_ptr<arrow::Int8Type> INT8;
extern const std::shared_ptr<arrow::Int16Type> INT16;
extern const std::shared_ptr<arrow::Int32Type> INT32;
extern const std::shared_ptr<arrow::Int64Type> INT64;
extern const std::shared_ptr<arrow::DateType> DATE;
extern const std::shared_ptr<arrow::TimestampType> TIMESTAMP;
extern const std::shared_ptr<arrow::FloatType> FLOAT;
extern const std::shared_ptr<arrow::DoubleType> DOUBLE;
extern const std::shared_ptr<arrow::StringType> STRING;