datasets 4.6.0__tar.gz → 4.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {datasets-4.6.0/src/datasets.egg-info → datasets-4.7.0}/PKG-INFO +2 -2
- {datasets-4.6.0 → datasets-4.7.0}/README.md +1 -1
- {datasets-4.6.0 → datasets-4.7.0}/setup.py +1 -1
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/__init__.py +1 -1
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/arrow_dataset.py +240 -3
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/arrow_writer.py +92 -7
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/dataset_dict.py +12 -1
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/__init__.py +2 -1
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/features.py +113 -4
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/iterable_dataset.py +16 -14
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/__init__.py +1 -1
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/json/json.py +91 -30
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/_dill.py +40 -3
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/extract.py +119 -7
- datasets-4.7.0/src/datasets/utils/json.py +119 -0
- {datasets-4.6.0 → datasets-4.7.0/src/datasets.egg-info}/PKG-INFO +2 -2
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets.egg-info/SOURCES.txt +2 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_arrow_dataset.py +58 -0
- datasets-4.7.0/tests/test_fingerprint_tokenizer_stability.py +45 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_iterable_dataset.py +28 -0
- {datasets-4.6.0 → datasets-4.7.0}/AUTHORS +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/LICENSE +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/pyproject.toml +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/setup.cfg +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/arrow_reader.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/builder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/combine.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/commands/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/commands/datasets_cli.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/commands/delete_from_hub.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/commands/env.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/commands/test.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/config.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/data_files.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/distributed.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/download/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/download/download_config.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/download/download_manager.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/download/streaming_download_manager.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/exceptions.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/_torchcodec.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/audio.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/image.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/nifti.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/pdf.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/translation.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/features/video.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/filesystems/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/filesystems/compression.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/fingerprint.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/formatting/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/formatting/formatting.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/formatting/jax_formatter.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/formatting/np_formatter.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/formatting/polars_formatter.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/formatting/tf_formatter.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/formatting/torch_formatter.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/hub.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/info.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/inspect.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/abc.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/csv.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/generator.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/json.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/parquet.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/spark.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/sql.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/io/text.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/load.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/naming.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/arrow/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/arrow/arrow.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/audiofolder/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/audiofolder/audiofolder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/cache/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/cache/cache.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/csv/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/csv/csv.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/eval/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/eval/eval.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/folder_based_builder/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/folder_based_builder/folder_based_builder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/generator/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/generator/generator.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/hdf5/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/hdf5/hdf5.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/imagefolder/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/imagefolder/imagefolder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/json/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/lance/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/lance/lance.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/niftifolder/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/niftifolder/niftifolder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/pandas/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/pandas/pandas.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/parquet/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/parquet/parquet.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/pdffolder/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/pdffolder/pdffolder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/spark/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/spark/spark.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/sql/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/sql/sql.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/text/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/text/text.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/videofolder/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/videofolder/videofolder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/webdataset/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/webdataset/_tenbin.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/webdataset/webdataset.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/xml/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/packaged_modules/xml/xml.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/parallel/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/parallel/parallel.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/search.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/splits.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/streaming.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/table.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/_dataset_viewer.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/_filelock.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/deprecation_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/doc_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/experimental.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/file_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/filelock.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/hub.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/info_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/logging.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/metadata.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/patching.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/py_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/resources/__init__.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/resources/creators.json +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/resources/languages.json +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/resources/multilingualities.json +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/resources/readme_structure.yaml +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/resources/size_categories.json +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/sharding.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/stratify.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/tf_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/tqdm.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/track.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/typing.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets/utils/version.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets.egg-info/dependency_links.txt +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets.egg-info/entry_points.txt +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets.egg-info/not-zip-safe +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets.egg-info/requires.txt +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/src/datasets.egg-info/top_level.txt +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_arrow_reader.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_arrow_writer.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_builder.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_data_files.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_dataset_dict.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_dataset_list.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_distributed.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_download_manager.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_exceptions.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_experimental.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_extract.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_file_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_filelock.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_filesystem.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_fingerprint.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_formatting.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_hub.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_info.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_info_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_inspect.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_load.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_metadata_util.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_offline_util.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_parallel.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_patching.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_py_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_search.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_sharding_utils.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_splits.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_streaming_download_manager.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_table.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_tqdm.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_upstream_hub.py +0 -0
- {datasets-4.6.0 → datasets-4.7.0}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: datasets
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.7.0
|
|
4
4
|
Summary: HuggingFace community-driven open-source library of datasets
|
|
5
5
|
Home-page: https://github.com/huggingface/datasets
|
|
6
6
|
Download-URL: https://github.com/huggingface/datasets/tags
|
|
@@ -272,7 +272,7 @@ from datasets import load_dataset
|
|
|
272
272
|
|
|
273
273
|
# Print all the available datasets
|
|
274
274
|
from huggingface_hub import list_datasets
|
|
275
|
-
print([dataset.id for dataset in list_datasets()])
|
|
275
|
+
print([dataset.id for dataset in list_datasets(limit=20)])
|
|
276
276
|
|
|
277
277
|
# Load a dataset and print the first example in the training set
|
|
278
278
|
squad_dataset = load_dataset('rajpurkar/squad')
|
|
@@ -84,7 +84,7 @@ from datasets import load_dataset
|
|
|
84
84
|
|
|
85
85
|
# Print all the available datasets
|
|
86
86
|
from huggingface_hub import list_datasets
|
|
87
|
-
print([dataset.id for dataset in list_datasets()])
|
|
87
|
+
print([dataset.id for dataset in list_datasets(limit=20)])
|
|
88
88
|
|
|
89
89
|
# Load a dataset and print the first example in the training set
|
|
90
90
|
squad_dataset = load_dataset('rajpurkar/squad')
|
|
@@ -233,7 +233,7 @@ EXTRAS_REQUIRE = {
|
|
|
233
233
|
|
|
234
234
|
setup(
|
|
235
235
|
name="datasets",
|
|
236
|
-
version="4.
|
|
236
|
+
version="4.7.0", # expected format is one of x.y.z.dev0, or x.y.z.rc1 or x.y.z (no to dashes, yes to dots)
|
|
237
237
|
description="HuggingFace community-driven open-source library of datasets",
|
|
238
238
|
long_description=open("README.md", encoding="utf-8").read(),
|
|
239
239
|
long_description_content_type="text/markdown",
|
|
@@ -981,6 +981,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
981
981
|
features: Optional[Features] = None,
|
|
982
982
|
info: Optional[DatasetInfo] = None,
|
|
983
983
|
split: Optional[NamedSplit] = None,
|
|
984
|
+
on_mixed_types: Optional[Literal["use_json"]] = None,
|
|
984
985
|
) -> "Dataset":
|
|
985
986
|
"""
|
|
986
987
|
Convert `dict` to a `pyarrow.Table` to create a [`Dataset`].
|
|
@@ -1000,9 +1001,109 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
1000
1001
|
Dataset information, like description, citation, etc.
|
|
1001
1002
|
split (`NamedSplit`, *optional*):
|
|
1002
1003
|
Name of the dataset split.
|
|
1004
|
+
on_mixed_types (`Literal["use_json"]`, *optional*, defaults to `None`):
|
|
1005
|
+
If "use_json", use the Json() type for mixed-types fields,
|
|
1006
|
+
i.e. unstructured fields that contain data without a predefined schema.
|
|
1007
|
+
In this case, a field with mixed type is set to Json().
|
|
1008
|
+
|
|
1009
|
+
This allow loading lists with a mix of strings/integers/floats
|
|
1010
|
+
for example, or dictionaries with arbitrary value types.
|
|
1011
|
+
|
|
1012
|
+
<Added version="4.7.0"/>
|
|
1003
1013
|
|
|
1004
1014
|
Returns:
|
|
1005
1015
|
[`Dataset`]
|
|
1016
|
+
|
|
1017
|
+
Examples:
|
|
1018
|
+
|
|
1019
|
+
Get a Dataset from a dictionary containing one list per column:
|
|
1020
|
+
|
|
1021
|
+
```py
|
|
1022
|
+
>>> ds = Dataset.from_dict({"text": ["hello there !", "general kenobi !"]})
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
Pass features to set the column types, e.g. for an image dataset:
|
|
1026
|
+
|
|
1027
|
+
```py
|
|
1028
|
+
>>> features = Features({"image": Image()})
|
|
1029
|
+
>>> ds = Dataset.from_dict({"image": ["path/to/image.png"]}, features=features)
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
Datasets are based on Arrow which is a columnar format, and therefore they expect every example to have the same
|
|
1033
|
+
type and subtypes, and dictionaries to have the same keys and values types.
|
|
1034
|
+
Loading a dataset errors out when fields have mismatching types, and fills missing fields in dictionaries with None so all dictionaries have the same keys and value types.
|
|
1035
|
+
|
|
1036
|
+
To avoid this and allow mixed-types without errors, you can use `on_mixed_types="use_json"` or specify `features=` with a [`Json`] type:
|
|
1037
|
+
|
|
1038
|
+
```py
|
|
1039
|
+
>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]})
|
|
1040
|
+
Traceback (most recent call last):
|
|
1041
|
+
...
|
|
1042
|
+
File "pyarrow/error.pxi", line 92, in pyarrow.lib.check_status
|
|
1043
|
+
pyarrow.lib.ArrowInvalid: Could not convert 'foo' with type str: tried to convert to int64
|
|
1044
|
+
|
|
1045
|
+
>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]}, on_mixed_types="use_json")
|
|
1046
|
+
>>> ds.features
|
|
1047
|
+
{'a': Json()}
|
|
1048
|
+
>>> list(ds["a"])
|
|
1049
|
+
[0, "foo", {"subfield": "bar"}]
|
|
1050
|
+
|
|
1051
|
+
>>> features = Features({"a": Json()})
|
|
1052
|
+
>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]}, features=features)
|
|
1053
|
+
>>> ds.features
|
|
1054
|
+
{'a': Json()}
|
|
1055
|
+
>>> list(ds["a"])
|
|
1056
|
+
[0, "foo", {"subfield": "bar"}]
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
This is also useful for lists of dictionaries with arbitrary keys and values, to avoid filling missing fields with None:
|
|
1060
|
+
|
|
1061
|
+
```py
|
|
1062
|
+
>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]})
|
|
1063
|
+
>>> ds.features
|
|
1064
|
+
{'a': List({'b': Value('int64'), 'c': Value('int64')})}
|
|
1065
|
+
>>> list(ds["a"])
|
|
1066
|
+
[[{'b': 0, 'c': None}, {'b': None, 'c': 0}]] # missing fields are filled with None
|
|
1067
|
+
|
|
1068
|
+
>>> features = Features({"a": List(Json())})
|
|
1069
|
+
>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]}, features=features)
|
|
1070
|
+
>>> ds.features
|
|
1071
|
+
{'a': List(Json())}
|
|
1072
|
+
>>> list(ds["a"])
|
|
1073
|
+
[[{'b': 0}, {'c': 0}]] # OK
|
|
1074
|
+
|
|
1075
|
+
>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]}, on_mixed_types="use_json")
|
|
1076
|
+
>>> ds.features
|
|
1077
|
+
{'a': List(Json())}
|
|
1078
|
+
>>> list(ds["a"])
|
|
1079
|
+
[[{'b': 0}, {'c': 0}]] # OK
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
Another example with tool calling data:
|
|
1083
|
+
|
|
1084
|
+
```py
|
|
1085
|
+
>>> messages = [
|
|
1086
|
+
... {"role": "user", "content": "Turn on the living room lights and play my electronic music playlist."},
|
|
1087
|
+
... {"role": "assistant", "tool_calls": [
|
|
1088
|
+
... {"type": "function", "function": {
|
|
1089
|
+
... "name": "control_light",
|
|
1090
|
+
... "arguments": {"room": "living room", "state": "on"}
|
|
1091
|
+
... }},
|
|
1092
|
+
... {"type": "function", "function": {
|
|
1093
|
+
... "name": "play_music",
|
|
1094
|
+
... "arguments": {"playlist": "electronic"} # mixed-type here since keys ["playlist"] and ["room", "state"] are different
|
|
1095
|
+
... }}]
|
|
1096
|
+
... },
|
|
1097
|
+
... {"role": "tool", "name": "control_light", "content": "The lights in the living room are now on."},
|
|
1098
|
+
... {"role": "tool", "name": "play_music", "content": "The music is now playing."},
|
|
1099
|
+
... {"role": "assistant", "content": "Done!"}
|
|
1100
|
+
... ]
|
|
1101
|
+
>>> ds = Dataset.from_dict({"messages": [messages]}, on_mixed_types="use_json")
|
|
1102
|
+
>>> ds.features
|
|
1103
|
+
{'messages': List({'role': Value('string'), 'content': Value('string'), 'tool_calls': List(Json()), 'name': Value('string')})}
|
|
1104
|
+
>>> ds[0]["messages"][1]["tool_calls"][0]["function"]["arguments"]
|
|
1105
|
+
{"room": "living room", "state": "on"}
|
|
1106
|
+
```
|
|
1006
1107
|
"""
|
|
1007
1108
|
if info is not None and features is not None and info.features != features:
|
|
1008
1109
|
raise ValueError(
|
|
@@ -1020,6 +1121,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
1020
1121
|
features.encode_column(data, col) if features is not None else data,
|
|
1021
1122
|
type=features[col] if features is not None else None,
|
|
1022
1123
|
col=col,
|
|
1124
|
+
on_mixed_types=on_mixed_types,
|
|
1023
1125
|
)
|
|
1024
1126
|
arrow_typed_mapping[col] = data
|
|
1025
1127
|
mapping = arrow_typed_mapping
|
|
@@ -1045,6 +1147,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
1045
1147
|
features: Optional[Features] = None,
|
|
1046
1148
|
info: Optional[DatasetInfo] = None,
|
|
1047
1149
|
split: Optional[NamedSplit] = None,
|
|
1150
|
+
on_mixed_types: Optional[Literal["use_json"]] = None,
|
|
1048
1151
|
) -> "Dataset":
|
|
1049
1152
|
"""
|
|
1050
1153
|
Convert a list of dicts to a `pyarrow.Table` to create a [`Dataset`]`.
|
|
@@ -1063,13 +1166,113 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
1063
1166
|
features (`Features`, optional): Dataset features.
|
|
1064
1167
|
info (`DatasetInfo`, optional): Dataset information, like description, citation, etc.
|
|
1065
1168
|
split (`NamedSplit`, optional): Name of the dataset split.
|
|
1169
|
+
on_mixed_types (`Literal["use_json"]`, *optional*, defaults to `None`):
|
|
1170
|
+
If "use_json", use the Json() type for mixed-types fields,
|
|
1171
|
+
i.e. unstructured fields that contain data without a predefined schema.
|
|
1172
|
+
In this case, a field with mixed type is set to Json().
|
|
1173
|
+
|
|
1174
|
+
This allow loading lists with a mix of strings/integers/floats
|
|
1175
|
+
for example, or dictionaries with arbitrary value types.
|
|
1176
|
+
|
|
1177
|
+
<Added version="4.7.0"/>
|
|
1066
1178
|
|
|
1067
1179
|
Returns:
|
|
1068
1180
|
[`Dataset`]
|
|
1181
|
+
|
|
1182
|
+
Examples:
|
|
1183
|
+
|
|
1184
|
+
Get a Dataset from a list containing the examples:
|
|
1185
|
+
|
|
1186
|
+
```py
|
|
1187
|
+
>>> ds = Dataset.from_list([{"text": "hello there !"}, {"text": "general kenobi !"}]})
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
Pass features to set the column types, e.g. for an image dataset:
|
|
1191
|
+
|
|
1192
|
+
```py
|
|
1193
|
+
>>> features = Features({"image": Image()})
|
|
1194
|
+
>>> ds = Dataset.from_list([{"image": "path/to/image.png"}], features=features)
|
|
1195
|
+
```
|
|
1196
|
+
|
|
1197
|
+
Datasets are based on Arrow which is a columnar format, and therefore they expect every example to have the same
|
|
1198
|
+
type and subtypes, and dictionaries to have the same keys and values types.
|
|
1199
|
+
Loading a dataset errors out when fields have mismatching types, and fills missing fields in dictionaries with None so all dictionaries have the same keys and value types.
|
|
1200
|
+
|
|
1201
|
+
To avoid this and allow mixed-types without errors, you can use `on_mixed_types="use_json"` or specify `features=` with a [`Json`] type:
|
|
1202
|
+
|
|
1203
|
+
```py
|
|
1204
|
+
>>> ds = Dataset.from_list([{"a": 0}, {"a": "foo"}, {"a": {"subfield": "bar"}}])
|
|
1205
|
+
Traceback (most recent call last):
|
|
1206
|
+
...
|
|
1207
|
+
File "pyarrow/error.pxi", line 92, in pyarrow.lib.check_status
|
|
1208
|
+
pyarrow.lib.ArrowInvalid: Could not convert 'foo' with type str: tried to convert to int64
|
|
1209
|
+
|
|
1210
|
+
>>> ds = Dataset.from_list([{"a": 0}, {"a": "foo"}, {"a": {"subfield": "bar"}}], on_mixed_types="use_json")
|
|
1211
|
+
>>> ds.features
|
|
1212
|
+
{'a': Json()}
|
|
1213
|
+
>>> list(ds["a"])
|
|
1214
|
+
[0, "foo", {"subfield": "bar"}]
|
|
1215
|
+
|
|
1216
|
+
>>> features = Features({"a": Json()})
|
|
1217
|
+
>>> ds = Dataset.from_list([{"a": 0}, {"a": "foo"}, {"a": {"subfield": "bar"}}], features=features)
|
|
1218
|
+
>>> ds.features
|
|
1219
|
+
{'a': Json()}
|
|
1220
|
+
>>> list(ds["a"])
|
|
1221
|
+
[0, "foo", {"subfield": "bar"}]
|
|
1222
|
+
```
|
|
1223
|
+
|
|
1224
|
+
This is also useful for lists of dictionaries with arbitrary keys and values, to avoid filling missing fields with None:
|
|
1225
|
+
|
|
1226
|
+
```py
|
|
1227
|
+
>>> ds = Dataset.from_list([{"a": [{"b": 0}, {"c": 0}]}])
|
|
1228
|
+
>>> ds.features
|
|
1229
|
+
{'a': List({'b': Value('int64'), 'c': Value('int64')})}
|
|
1230
|
+
>>> list(ds["a"])
|
|
1231
|
+
[[{'b': 0, 'c': None}, {'b': None, 'c': 0}]] # missing fields are filled with None
|
|
1232
|
+
|
|
1233
|
+
>>> features = Features({"a": List(Json())})
|
|
1234
|
+
>>> ds = Dataset.from_list([{"a": [{"b": 0}, {"c": 0}]}], features=features)
|
|
1235
|
+
>>> ds.features
|
|
1236
|
+
{'a': List(Json())}
|
|
1237
|
+
>>> list(ds["a"])
|
|
1238
|
+
[[{'b': 0}, {'c': 0}]] # OK
|
|
1239
|
+
|
|
1240
|
+
>>> ds = Dataset.from_list([{"a": [{"b": 0}, {"c": 0}]}], on_mixed_types="use_json")
|
|
1241
|
+
>>> ds.features
|
|
1242
|
+
{'a': List(Json())}
|
|
1243
|
+
>>> list(ds["a"])
|
|
1244
|
+
[[{'b': 0}, {'c': 0}]] # OK
|
|
1245
|
+
```
|
|
1246
|
+
|
|
1247
|
+
Another example with tool calling data:
|
|
1248
|
+
|
|
1249
|
+
```py
|
|
1250
|
+
>>> messages = [
|
|
1251
|
+
... {"role": "user", "content": "Turn on the living room lights and play my electronic music playlist."},
|
|
1252
|
+
... {"role": "assistant", "tool_calls": [
|
|
1253
|
+
... {"type": "function", "function": {
|
|
1254
|
+
... "name": "control_light",
|
|
1255
|
+
... "arguments": {"room": "living room", "state": "on"}
|
|
1256
|
+
... }},
|
|
1257
|
+
... {"type": "function", "function": {
|
|
1258
|
+
... "name": "play_music",
|
|
1259
|
+
... "arguments": {"playlist": "electronic"} # mixed-type here since keys ["playlist"] and ["room", "state"] are different
|
|
1260
|
+
... }}]
|
|
1261
|
+
... },
|
|
1262
|
+
... {"role": "tool", "name": "control_light", "content": "The lights in the living room are now on."},
|
|
1263
|
+
... {"role": "tool", "name": "play_music", "content": "The music is now playing."},
|
|
1264
|
+
... {"role": "assistant", "content": "Done!"}
|
|
1265
|
+
... ]
|
|
1266
|
+
>>> ds = Dataset.from_list([{"messages": messages}], on_mixed_types="use_json")
|
|
1267
|
+
>>> ds.features
|
|
1268
|
+
{'messages': List({'role': Value('string'), 'content': Value('string'), 'tool_calls': List(Json()), 'name': Value('string')})}
|
|
1269
|
+
>>> ds[0]["messages"][1]["tool_calls"][0]["function"]["arguments"]
|
|
1270
|
+
{"room": "living room", "state": "on"}
|
|
1271
|
+
```
|
|
1069
1272
|
"""
|
|
1070
1273
|
# for simplicity and consistency wrt OptimizedTypedSequence we do not use InMemoryTable.from_pylist here
|
|
1071
1274
|
mapping = {k: [r.get(k) for r in mapping] for k in mapping[0]} if mapping else {}
|
|
1072
|
-
return cls.from_dict(mapping, features, info, split)
|
|
1275
|
+
return cls.from_dict(mapping, features, info, split, on_mixed_types=on_mixed_types)
|
|
1073
1276
|
|
|
1074
1277
|
@staticmethod
|
|
1075
1278
|
def from_csv(
|
|
@@ -3016,6 +3219,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
3016
3219
|
new_fingerprint: Optional[str] = None,
|
|
3017
3220
|
desc: Optional[str] = None,
|
|
3018
3221
|
try_original_type: Optional[bool] = True,
|
|
3222
|
+
on_mixed_types: Optional[Literal["use_json"]] = "use_json",
|
|
3019
3223
|
) -> "Dataset":
|
|
3020
3224
|
"""
|
|
3021
3225
|
Apply a function to all the examples in the table (individually or in batches) and update the table.
|
|
@@ -3104,6 +3308,15 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
3104
3308
|
try_original_type (`Optional[bool]`, defaults to `True`):
|
|
3105
3309
|
Try to keep the types of the original columns (e.g. int32 -> int32).
|
|
3106
3310
|
Set to False if you want to always infer new types.
|
|
3311
|
+
on_mixed_types (`Literal["use_json"]`, *optional*, defaults to `None`):
|
|
3312
|
+
If "use_json", use the Json() type for mixed-types fields,
|
|
3313
|
+
i.e. unstructured fields that contain data without a predefined schema.
|
|
3314
|
+
In this case, a field with mixed type is set to Json().
|
|
3315
|
+
|
|
3316
|
+
This allow loading lists with a mix of strings/integers/floats
|
|
3317
|
+
for example, or dictionaries with arbitrary value types.
|
|
3318
|
+
|
|
3319
|
+
<Added version="4.7.0"/>
|
|
3107
3320
|
|
|
3108
3321
|
Example:
|
|
3109
3322
|
|
|
@@ -3205,6 +3418,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
3205
3418
|
"disable_nullable": disable_nullable,
|
|
3206
3419
|
"fn_kwargs": fn_kwargs,
|
|
3207
3420
|
"try_original_type": try_original_type,
|
|
3421
|
+
"on_mixed_types": on_mixed_types,
|
|
3208
3422
|
}
|
|
3209
3423
|
|
|
3210
3424
|
if new_fingerprint is None:
|
|
@@ -3459,6 +3673,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
3459
3673
|
rank: Optional[int] = None,
|
|
3460
3674
|
offset: int = 0,
|
|
3461
3675
|
try_original_type: Optional[bool] = True,
|
|
3676
|
+
on_mixed_types: Optional[Literal["use_json"]] = "use_json",
|
|
3462
3677
|
) -> Iterable[tuple[Optional[int], bool, Union[int, "Dataset"]]]:
|
|
3463
3678
|
"""Apply a function to all the elements in the table (individually or in batches)
|
|
3464
3679
|
and update the table (if function does update examples).
|
|
@@ -3503,6 +3718,15 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
3503
3718
|
try_original_type: (`Optional[bool]`, defaults to `True`):
|
|
3504
3719
|
Try to keep the types of the original columns (e.g. int32 -> int32).
|
|
3505
3720
|
Set to False if you want to always infer new types.
|
|
3721
|
+
on_mixed_types (`Literal["use_json"]`, *optional*, defaults to `None`):
|
|
3722
|
+
If "use_json", use the Json() type for mixed-types fields,
|
|
3723
|
+
i.e. unstructured fields that contain data without a predefined schema.
|
|
3724
|
+
In this case, a field with mixed type is set to Json().
|
|
3725
|
+
|
|
3726
|
+
This allow loading lists with a mix of strings/integers/floats
|
|
3727
|
+
for example, or dictionaries with arbitrary value types.
|
|
3728
|
+
|
|
3729
|
+
<Added version="4.7.0"/>
|
|
3506
3730
|
"""
|
|
3507
3731
|
if fn_kwargs is None:
|
|
3508
3732
|
fn_kwargs = {}
|
|
@@ -3659,6 +3883,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
3659
3883
|
update_features=update_features,
|
|
3660
3884
|
fingerprint=new_fingerprint,
|
|
3661
3885
|
disable_nullable=disable_nullable,
|
|
3886
|
+
on_mixed_types=on_mixed_types,
|
|
3662
3887
|
)
|
|
3663
3888
|
else:
|
|
3664
3889
|
buf_writer = None
|
|
@@ -3673,6 +3898,7 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
3673
3898
|
update_features=update_features,
|
|
3674
3899
|
fingerprint=new_fingerprint,
|
|
3675
3900
|
disable_nullable=disable_nullable,
|
|
3901
|
+
on_mixed_types=on_mixed_types,
|
|
3676
3902
|
)
|
|
3677
3903
|
return buf_writer, writer, tmp_file
|
|
3678
3904
|
|
|
@@ -5628,9 +5854,10 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
5628
5854
|
)
|
|
5629
5855
|
except (Exception, KeyboardInterrupt):
|
|
5630
5856
|
tmp_file.close()
|
|
5631
|
-
|
|
5632
|
-
Path(tmp_file.name).unlink()
|
|
5857
|
+
Path(tmp_file.name).unlink()
|
|
5633
5858
|
raise
|
|
5859
|
+
tmp_file.close()
|
|
5860
|
+
Path(tmp_file.name).unlink()
|
|
5634
5861
|
additions.append(shard_addition)
|
|
5635
5862
|
yield job_id, False, 1
|
|
5636
5863
|
|
|
@@ -5680,6 +5907,16 @@ class Dataset(DatasetInfoMixin, IndexableMixin, TensorflowDatasetMixin):
|
|
|
5680
5907
|
additions: list[CommitOperationAdd] = []
|
|
5681
5908
|
|
|
5682
5909
|
num_jobs = num_proc or 1
|
|
5910
|
+
if num_shards <= 1:
|
|
5911
|
+
logger.warning(
|
|
5912
|
+
f"Setting num_proc from {num_jobs} back to 1 for the {split} split to disable multiprocessing as it only contains one shard."
|
|
5913
|
+
)
|
|
5914
|
+
num_jobs = 1
|
|
5915
|
+
elif num_shards < num_jobs:
|
|
5916
|
+
logger.warning(
|
|
5917
|
+
f"Setting num_proc from {num_jobs} to {num_shards} for the {split} split as it only contains {num_shards} shards."
|
|
5918
|
+
)
|
|
5919
|
+
num_proc = num_shards
|
|
5683
5920
|
kwargs_iterable = [
|
|
5684
5921
|
{
|
|
5685
5922
|
"self": self.shard(num_shards=num_jobs, index=job_id, contiguous=True),
|
|
@@ -13,14 +13,16 @@
|
|
|
13
13
|
# Lint as: python3
|
|
14
14
|
"""To write records into Parquet files."""
|
|
15
15
|
|
|
16
|
+
import io
|
|
16
17
|
import json
|
|
17
18
|
import sys
|
|
18
19
|
from collections.abc import Iterable
|
|
19
|
-
from typing import Any, Optional
|
|
20
|
+
from typing import Any, Literal, Optional
|
|
20
21
|
|
|
21
22
|
import fsspec
|
|
22
23
|
import numpy as np
|
|
23
24
|
import pyarrow as pa
|
|
25
|
+
import pyarrow.json as paj
|
|
24
26
|
import pyarrow.parquet as pq
|
|
25
27
|
from fsspec.core import url_to_fs
|
|
26
28
|
|
|
@@ -43,6 +45,16 @@ from .filesystems import is_remote_filesystem
|
|
|
43
45
|
from .info import DatasetInfo
|
|
44
46
|
from .table import array_cast, cast_array_to_feature, embed_table_storage, table_cast
|
|
45
47
|
from .utils import logging
|
|
48
|
+
from .utils.json import (
|
|
49
|
+
find_mixed_struct_types_field_paths,
|
|
50
|
+
get_json_field_path_from_pyarrow_json_error,
|
|
51
|
+
get_json_field_paths_from_feature,
|
|
52
|
+
insert_json_field_path,
|
|
53
|
+
json_encode_field,
|
|
54
|
+
json_encode_fields_in_json_lines,
|
|
55
|
+
set_json_types_in_feature,
|
|
56
|
+
ujson_dumps,
|
|
57
|
+
)
|
|
46
58
|
from .utils.py_utils import asdict, convert_file_size_to_int, first_non_null_non_empty_value
|
|
47
59
|
|
|
48
60
|
|
|
@@ -204,6 +216,7 @@ class TypedSequence:
|
|
|
204
216
|
type: Optional[FeatureType] = None,
|
|
205
217
|
try_type: Optional[FeatureType] = None,
|
|
206
218
|
optimized_int_type: Optional[FeatureType] = None,
|
|
219
|
+
on_mixed_types: Optional[Literal["use_json"]] = None,
|
|
207
220
|
):
|
|
208
221
|
# assert type is None or try_type is None,
|
|
209
222
|
if type is not None and try_type is not None:
|
|
@@ -213,6 +226,7 @@ class TypedSequence:
|
|
|
213
226
|
self.type = type
|
|
214
227
|
self.try_type = try_type # is ignored if it doesn't match the data
|
|
215
228
|
self.optimized_int_type = optimized_int_type
|
|
229
|
+
self.on_mixed_types = on_mixed_types
|
|
216
230
|
# when trying a type (is ignored if data is not compatible)
|
|
217
231
|
self.trying_type = self.try_type is not None
|
|
218
232
|
self.trying_int_optimization = optimized_int_type is not None and type is None and try_type is None
|
|
@@ -231,7 +245,7 @@ class TypedSequence:
|
|
|
231
245
|
FeatureType: inferred feature type of the sequence.
|
|
232
246
|
"""
|
|
233
247
|
if self._inferred_type is None:
|
|
234
|
-
|
|
248
|
+
pa.array(self)
|
|
235
249
|
return self._inferred_type
|
|
236
250
|
|
|
237
251
|
@staticmethod
|
|
@@ -274,6 +288,12 @@ class TypedSequence:
|
|
|
274
288
|
return data, None
|
|
275
289
|
|
|
276
290
|
def __arrow_array__(self, type: Optional[pa.DataType] = None):
|
|
291
|
+
out = self._arrow_array(type=type)
|
|
292
|
+
if self._inferred_type is None:
|
|
293
|
+
self._inferred_type = generate_from_arrow_type(out.type)
|
|
294
|
+
return out
|
|
295
|
+
|
|
296
|
+
def _arrow_array(self, type: Optional[pa.DataType] = None):
|
|
277
297
|
"""This function is called when calling pa.array(typed_sequence)"""
|
|
278
298
|
|
|
279
299
|
if type is not None:
|
|
@@ -292,6 +312,7 @@ class TypedSequence:
|
|
|
292
312
|
get_nested_type(self.optimized_int_type) if self.optimized_int_type is not None else None
|
|
293
313
|
)
|
|
294
314
|
trying_cast_to_python_objects = False
|
|
315
|
+
json_field_paths = []
|
|
295
316
|
try:
|
|
296
317
|
# custom pyarrow types
|
|
297
318
|
if isinstance(pa_type, _ArrayXDExtensionType):
|
|
@@ -305,7 +326,25 @@ class TypedSequence:
|
|
|
305
326
|
out = list_of_np_array_to_pyarrow_listarray(data)
|
|
306
327
|
else:
|
|
307
328
|
trying_cast_to_python_objects = True
|
|
308
|
-
|
|
329
|
+
examples = data
|
|
330
|
+
# find fields to json-encode
|
|
331
|
+
if self.on_mixed_types == "use_json" and type is None:
|
|
332
|
+
json_field_paths = find_mixed_struct_types_field_paths(examples, allow_root=True)
|
|
333
|
+
elif type is not None:
|
|
334
|
+
json_field_paths = get_json_field_paths_from_feature(type)
|
|
335
|
+
# json encode if needed
|
|
336
|
+
if json_field_paths:
|
|
337
|
+
for json_field_path in json_field_paths:
|
|
338
|
+
examples = [json_encode_field(examples, json_field_path) for examples in examples]
|
|
339
|
+
# to arrow array
|
|
340
|
+
out = pa.array(cast_to_python_objects(examples, only_1d_for_numpy=True))
|
|
341
|
+
# cast to json type if needed
|
|
342
|
+
if json_field_paths:
|
|
343
|
+
pa_table = pa.Table.from_arrays([out], names=["obj"])
|
|
344
|
+
features = Features.from_arrow_schema(pa_table.schema)
|
|
345
|
+
feature = set_json_types_in_feature(features["obj"], json_field_paths)
|
|
346
|
+
pa_table = table_cast(pa_table, Features({"obj": feature}).arrow_schema)
|
|
347
|
+
out = pa_table[0] # get the "obj" column
|
|
309
348
|
# use smaller integer precisions if possible
|
|
310
349
|
if self.trying_int_optimization:
|
|
311
350
|
if pa.types.is_int64(out.type):
|
|
@@ -326,6 +365,7 @@ class TypedSequence:
|
|
|
326
365
|
return out
|
|
327
366
|
except (
|
|
328
367
|
TypeError,
|
|
368
|
+
pa.lib.ArrowTypeError,
|
|
329
369
|
pa.lib.ArrowInvalid,
|
|
330
370
|
pa.lib.ArrowNotImplementedError,
|
|
331
371
|
) as e: # handle type errors and overflows
|
|
@@ -372,8 +412,46 @@ class TypedSequence:
|
|
|
372
412
|
optimized_int_pa_type_str = np.dtype(optimized_int_pa_type.to_pandas_dtype()).name
|
|
373
413
|
logger.info(f"Failed to cast a sequence to {optimized_int_pa_type_str}. Falling back to int64.")
|
|
374
414
|
return out
|
|
375
|
-
elif trying_cast_to_python_objects and
|
|
376
|
-
|
|
415
|
+
elif trying_cast_to_python_objects and (
|
|
416
|
+
"Could not convert" in str(e) or "cannot mix struct and non-struct" in str(e) or "Expected " in str(e)
|
|
417
|
+
):
|
|
418
|
+
try: # third chance
|
|
419
|
+
out = pa.array(cast_to_python_objects(data, only_1d_for_numpy=True, optimize_list_casting=False))
|
|
420
|
+
except (pa.ArrowInvalid, pa.ArrowTypeError) as ee:
|
|
421
|
+
# in case of mixed types, we use the JSON Lines reader in pyarrow to locate them and set them to json fields
|
|
422
|
+
if self.on_mixed_types == "use_json" and (
|
|
423
|
+
"Could not convert " in str(ee)
|
|
424
|
+
or "cannot mix struct and non-struct" in str(ee)
|
|
425
|
+
or "Expected " in str(ee)
|
|
426
|
+
):
|
|
427
|
+
# we use "obj" to have valid JSON Lines since data may contain lists
|
|
428
|
+
original_batch = "\n".join([ujson_dumps({"obj": example}) for example in data]).encode()
|
|
429
|
+
json_field_paths = [["obj"] + json_field_path for json_field_path in json_field_paths]
|
|
430
|
+
batch = json_encode_fields_in_json_lines(original_batch, json_field_paths)
|
|
431
|
+
pa_table = None
|
|
432
|
+
while True:
|
|
433
|
+
try: # fourth chance
|
|
434
|
+
pa_table = paj.read_json(
|
|
435
|
+
io.BytesIO(batch), read_options=paj.ReadOptions(use_threads=False)
|
|
436
|
+
)
|
|
437
|
+
break
|
|
438
|
+
except pa.ArrowInvalid as eee:
|
|
439
|
+
if "JSON parse error: Column(" in str(eee) and ") changed from" in str(eee):
|
|
440
|
+
json_field_path = get_json_field_path_from_pyarrow_json_error(str(eee))
|
|
441
|
+
insert_json_field_path(json_field_paths, json_field_path)
|
|
442
|
+
batch = json_encode_fields_in_json_lines(original_batch, json_field_paths)
|
|
443
|
+
else:
|
|
444
|
+
break
|
|
445
|
+
if pa_table is not None:
|
|
446
|
+
features = Features.from_arrow_schema(pa_table.schema)
|
|
447
|
+
features = set_json_types_in_feature(features, json_field_paths)
|
|
448
|
+
pa_table = table_cast(pa_table, features.arrow_schema)
|
|
449
|
+
out = pa_table[0] # get the "obj" column
|
|
450
|
+
return out
|
|
451
|
+
else:
|
|
452
|
+
raise
|
|
453
|
+
else:
|
|
454
|
+
raise
|
|
377
455
|
if type is not None:
|
|
378
456
|
out = cast_array_to_feature(out, type, allow_primitive_to_str=True, allow_decimal_to_str=True)
|
|
379
457
|
return out
|
|
@@ -389,6 +467,7 @@ class OptimizedTypedSequence(TypedSequence):
|
|
|
389
467
|
try_type: Optional[FeatureType] = None,
|
|
390
468
|
col: Optional[str] = None,
|
|
391
469
|
optimized_int_type: Optional[FeatureType] = None,
|
|
470
|
+
on_mixed_types: Optional[Literal["use_json"]] = None,
|
|
392
471
|
):
|
|
393
472
|
optimized_int_type_by_col = {
|
|
394
473
|
"attention_mask": Value("int8"), # binary tensor
|
|
@@ -400,7 +479,9 @@ class OptimizedTypedSequence(TypedSequence):
|
|
|
400
479
|
}
|
|
401
480
|
if type is None and try_type is None:
|
|
402
481
|
optimized_int_type = optimized_int_type_by_col.get(col, None)
|
|
403
|
-
super().__init__(
|
|
482
|
+
super().__init__(
|
|
483
|
+
data, type=type, try_type=try_type, optimized_int_type=optimized_int_type, on_mixed_types=on_mixed_types
|
|
484
|
+
)
|
|
404
485
|
|
|
405
486
|
|
|
406
487
|
class ArrowWriter:
|
|
@@ -416,6 +497,7 @@ class ArrowWriter:
|
|
|
416
497
|
writer_batch_size: Optional[int] = None,
|
|
417
498
|
disable_nullable: bool = False,
|
|
418
499
|
update_features: bool = False,
|
|
500
|
+
on_mixed_types: Optional[Literal["use_json"]] = "use_json",
|
|
419
501
|
with_metadata: bool = True,
|
|
420
502
|
unit: str = "examples",
|
|
421
503
|
embed_local_files: bool = False,
|
|
@@ -455,6 +537,7 @@ class ArrowWriter:
|
|
|
455
537
|
or config.DEFAULT_MAX_BATCH_SIZE
|
|
456
538
|
)
|
|
457
539
|
self.update_features = update_features
|
|
540
|
+
self.on_mixed_types = on_mixed_types
|
|
458
541
|
self.with_metadata = with_metadata
|
|
459
542
|
self.unit = unit
|
|
460
543
|
self.embed_local_files = embed_local_files
|
|
@@ -654,7 +737,9 @@ class ArrowWriter:
|
|
|
654
737
|
if try_features is not None and col in try_features and try_original_type
|
|
655
738
|
else None
|
|
656
739
|
)
|
|
657
|
-
typed_sequence = OptimizedTypedSequence(
|
|
740
|
+
typed_sequence = OptimizedTypedSequence(
|
|
741
|
+
col_values, type=col_type, try_type=col_try_type, col=col, on_mixed_types=self.on_mixed_types
|
|
742
|
+
)
|
|
658
743
|
arrays.append(pa.array(typed_sequence))
|
|
659
744
|
inferred_features[col] = typed_sequence.get_inferred_type()
|
|
660
745
|
schema = inferred_features.arrow_schema if self.pa_writer is None else self.schema
|
|
@@ -11,7 +11,7 @@ import time
|
|
|
11
11
|
from collections.abc import Sequence
|
|
12
12
|
from functools import partial
|
|
13
13
|
from pathlib import Path
|
|
14
|
-
from typing import Callable, Optional, Union
|
|
14
|
+
from typing import Callable, Literal, Optional, Union
|
|
15
15
|
|
|
16
16
|
import fsspec
|
|
17
17
|
import numpy as np
|
|
@@ -836,6 +836,7 @@ class DatasetDict(dict[Union[str, NamedSplit], "Dataset"]):
|
|
|
836
836
|
num_proc: Optional[int] = None,
|
|
837
837
|
desc: Optional[str] = None,
|
|
838
838
|
try_original_type: Optional[bool] = True,
|
|
839
|
+
on_mixed_types: Optional[Literal["use_json"]] = None,
|
|
839
840
|
) -> "DatasetDict":
|
|
840
841
|
"""
|
|
841
842
|
Apply a function to all the examples in the table (individually or in batches) and update the table.
|
|
@@ -920,6 +921,15 @@ class DatasetDict(dict[Union[str, NamedSplit], "Dataset"]):
|
|
|
920
921
|
try_original_type (`Optional[bool]`, defaults to `True`):
|
|
921
922
|
Try to keep the types of the original columns (e.g. int32 -> int32).
|
|
922
923
|
Set to False if you want to always infer new types.
|
|
924
|
+
on_mixed_types (`Literal["use_json"]`, *optional*, defaults to `None`):
|
|
925
|
+
If "use_json", use the Json() type for mixed-types fields,
|
|
926
|
+
i.e. unstructured fields that contain data without a predefined schema.
|
|
927
|
+
In this case, a field with mixed type is set to Json().
|
|
928
|
+
|
|
929
|
+
This allow loading lists with a mix of strings/integers/floats
|
|
930
|
+
for example, or dictionaries with arbitrary value types.
|
|
931
|
+
|
|
932
|
+
<Added version="4.7.0"/>
|
|
923
933
|
|
|
924
934
|
Example:
|
|
925
935
|
|
|
@@ -969,6 +979,7 @@ class DatasetDict(dict[Union[str, NamedSplit], "Dataset"]):
|
|
|
969
979
|
num_proc=num_proc,
|
|
970
980
|
desc=desc,
|
|
971
981
|
try_original_type=try_original_type,
|
|
982
|
+
on_mixed_types=on_mixed_types,
|
|
972
983
|
)
|
|
973
984
|
|
|
974
985
|
if with_split:
|
|
@@ -6,6 +6,7 @@ __all__ = [
|
|
|
6
6
|
"Array5D",
|
|
7
7
|
"ClassLabel",
|
|
8
8
|
"Features",
|
|
9
|
+
"Json",
|
|
9
10
|
"LargeList",
|
|
10
11
|
"List",
|
|
11
12
|
"Sequence",
|
|
@@ -18,7 +19,7 @@ __all__ = [
|
|
|
18
19
|
"Nifti",
|
|
19
20
|
]
|
|
20
21
|
from .audio import Audio
|
|
21
|
-
from .features import Array2D, Array3D, Array4D, Array5D, ClassLabel, Features, LargeList, List, Sequence, Value
|
|
22
|
+
from .features import Array2D, Array3D, Array4D, Array5D, ClassLabel, Features, Json, LargeList, List, Sequence, Value
|
|
22
23
|
from .image import Image
|
|
23
24
|
from .nifti import Nifti
|
|
24
25
|
from .pdf import Pdf
|