| 964 | } |
| 965 | |
| 966 | Status ConvertMap(PandasOptions options, const ChunkedArray& data, |
| 967 | PyObject** out_values) { |
| 968 | // Get columns of underlying key/item arrays |
| 969 | std::vector<std::shared_ptr<Array>> key_arrays; |
| 970 | std::vector<std::shared_ptr<Array>> item_arrays; |
| 971 | for (int c = 0; c < data.num_chunks(); ++c) { |
| 972 | const auto& map_arr = checked_cast<const MapArray&>(*data.chunk(c)); |
| 973 | key_arrays.emplace_back(map_arr.keys()); |
| 974 | item_arrays.emplace_back(map_arr.items()); |
| 975 | } |
| 976 | |
| 977 | const auto& map_type = checked_cast<const MapType&>(*data.type()); |
| 978 | auto key_type = map_type.key_type(); |
| 979 | auto item_type = map_type.item_type(); |
| 980 | |
| 981 | // ARROW-6899: Convert dictionary-encoded children to dense instead of |
| 982 | // failing below. A more efficient conversion than this could be done later |
| 983 | if (key_type->id() == Type::DICTIONARY) { |
| 984 | auto dense_type = checked_cast<const DictionaryType&>(*key_type).value_type(); |
| 985 | RETURN_NOT_OK(DecodeDictionaries(options.pool, dense_type, &key_arrays)); |
| 986 | key_type = dense_type; |
| 987 | } |
| 988 | if (item_type->id() == Type::DICTIONARY) { |
| 989 | auto dense_type = checked_cast<const DictionaryType&>(*item_type).value_type(); |
| 990 | RETURN_NOT_OK(DecodeDictionaries(options.pool, dense_type, &item_arrays)); |
| 991 | item_type = dense_type; |
| 992 | } |
| 993 | |
| 994 | // See notes in MakeInnerOptions. |
| 995 | options = MakeInnerOptions(std::move(options)); |
| 996 | // Don't blindly convert because timestamps in lists are handled differently. |
| 997 | options.timestamp_as_object = true; |
| 998 | |
| 999 | auto flat_keys = std::make_shared<ChunkedArray>(key_arrays, key_type); |
| 1000 | auto flat_items = std::make_shared<ChunkedArray>(item_arrays, item_type); |
| 1001 | OwnedRefNoGIL owned_numpy_keys; |
| 1002 | RETURN_NOT_OK( |
| 1003 | ConvertChunkedArrayToPandas(options, flat_keys, nullptr, owned_numpy_keys.ref())); |
| 1004 | OwnedRefNoGIL owned_numpy_items; |
| 1005 | RETURN_NOT_OK( |
| 1006 | ConvertChunkedArrayToPandas(options, flat_items, nullptr, owned_numpy_items.ref())); |
| 1007 | PyArrayObject* py_keys = reinterpret_cast<PyArrayObject*>(owned_numpy_keys.obj()); |
| 1008 | PyArrayObject* py_items = reinterpret_cast<PyArrayObject*>(owned_numpy_items.obj()); |
| 1009 | |
| 1010 | if (options.maps_as_pydicts == MapConversionType::DEFAULT) { |
| 1011 | // The default behavior to express an Arrow MAP as a list of [(key, value), ...] pairs |
| 1012 | OwnedRef list_item; |
| 1013 | return ConvertMapHelper( |
| 1014 | [&list_item](int64_t num_pairs) { |
| 1015 | list_item.reset(PyList_New(num_pairs)); |
| 1016 | return CheckPyError(); |
| 1017 | }, |
| 1018 | [&list_item](int64_t idx, OwnedRef& key_value, OwnedRef& item_value) { |
| 1019 | PyList_SET_ITEM(list_item.obj(), idx, |
| 1020 | PyTuple_Pack(2, key_value.obj(), item_value.obj())); |
| 1021 | return CheckPyError(); |
| 1022 | }, |
| 1023 | [&list_item] { return list_item.detach(); }, data, py_keys, py_items, item_arrays, |
no test coverage detected