MCPcopy Create free account
hub / github.com/apache/arrow / ConvertListsLike

Function ConvertListsLike

python/pyarrow/src/arrow/python/arrow_to_pandas.cc:759–834  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

757
758template <typename T>
759enable_if_list_like<T, Status> ConvertListsLike(PandasOptions options,
760 const ChunkedArray& data,
761 PyObject** out_values) {
762 using ListArrayT = typename TypeTraits<T>::ArrayType;
763 // Get column of underlying value arrays
764 ArrayVector value_arrays;
765 for (int c = 0; c < data.num_chunks(); c++) {
766 const auto& arr = checked_cast<const ListArrayT&>(*data.chunk(c));
767 // values() does not account for offsets, so we need to slice into it.
768 // We can't use Flatten(), because it removes the values behind a null list
769 // value, and that makes the offsets into original list values and our
770 // flattened_values array different.
771 std::shared_ptr<Array> flattened_values = arr.values()->Slice(
772 arr.value_offset(0), arr.value_offset(arr.length()) - arr.value_offset(0));
773 if (arr.value_type()->id() == Type::EXTENSION) {
774 const auto& arr_ext = checked_cast<const ExtensionArray&>(*flattened_values);
775 value_arrays.emplace_back(arr_ext.storage());
776 } else {
777 value_arrays.emplace_back(flattened_values);
778 }
779 }
780
781 using ListArrayType = typename ListArrayT::TypeClass;
782 const auto& list_type = checked_cast<const ListArrayType&>(*data.type());
783 auto value_type = list_type.value_type();
784 if (value_type->id() == Type::EXTENSION) {
785 value_type = checked_cast<const ExtensionType&>(*value_type).storage_type();
786 }
787
788 auto flat_column = std::make_shared<ChunkedArray>(value_arrays, value_type);
789
790 options = MakeInnerOptions(std::move(options));
791
792 OwnedRefNoGIL owned_numpy_array;
793 RETURN_NOT_OK(ConvertChunkedArrayToPandas(options, flat_column, nullptr,
794 owned_numpy_array.ref()));
795 PyObject* numpy_array = owned_numpy_array.obj();
796 ARROW_DCHECK(PyArray_Check(numpy_array));
797
798 int64_t chunk_offset = 0;
799 for (int c = 0; c < data.num_chunks(); c++) {
800 const auto& arr = checked_cast<const ListArrayT&>(*data.chunk(c));
801 const bool has_nulls = data.null_count() > 0;
802 for (int64_t i = 0; i < arr.length(); ++i) {
803 if (has_nulls && arr.IsNull(i)) {
804 Py_INCREF(Py_None);
805 *out_values = Py_None;
806 } else {
807 // Need to subtract value_offset(0) since the original chunk might be a slice
808 // into another array.
809 OwnedRef start(PyLong_FromLongLong(arr.value_offset(i) + chunk_offset -
810 arr.value_offset(0)));
811 OwnedRef end(PyLong_FromLongLong(arr.value_offset(i + 1) + chunk_offset -
812 arr.value_offset(0)));
813 OwnedRef slice(PySlice_New(start.obj(), end.obj(), nullptr));
814
815 if (ARROW_PREDICT_FALSE(slice.obj() == nullptr)) {
816 // Fall out of loop, will return from RETURN_IF_PYERROR

Callers

nothing calls this directly

Calls 15

MakeInnerOptionsFunction · 0.85
emplace_backMethod · 0.80
storage_typeMethod · 0.80
OKFunction · 0.50
num_chunksMethod · 0.45
SliceMethod · 0.45
valuesMethod · 0.45
value_offsetMethod · 0.45
lengthMethod · 0.45
idMethod · 0.45
value_typeMethod · 0.45

Tested by

no test coverage detected