# Características del conjunto de datos

[Features](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Features) define la estructura interna de un conjunto de datos. Se utiliza para especificar el formato de serialización subyacente. Lo más interesante para ti es que [Features](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Features) contiene información de alto nivel sobre todo, desde los nombres y tipos de columnas hasta el [ClassLabel](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.ClassLabel). Puedes pensar en [Features](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Features) como la columna vertebral de un conjunto de datos.

El formato [Features](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Features) es simple: `dict[column_name, column_type]`. Es un diccionario de pares de nombre de columna y tipo de columna. El tipo de columna ofrece una amplia gama de opciones para describir el tipo de datos que tienes.

Veamos las características del conjunto de datos MRPC del benchmark GLUE:

```py
>>> from datasets import load_dataset
>>> dataset = load_dataset('nyu-mll/glue', 'mrpc', split='train')
>>> dataset.features
{'idx': Value('int32'),
 'label': ClassLabel(names=['not_equivalent', 'equivalent']),
 'sentence1': Value('string'),
 'sentence2': Value('string'),
}
```

La función [Value](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Value) le indica a 🤗 Datasets:

- El tipo de datos `idx` es `int32`.
- Los tipos de datos `sentence1` y `sentence2` son `string`.

🤗 Datasets admite muchos otros tipos de datos, como `bool`, `float32` y `binary`, por nombrar solo algunos.

> [!TIP]
> Consulte [Value](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Value) para obtener la lista completa de tipos de datos admitidos.

La función [ClassLabel](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.ClassLabel) informa a 🤗 Datasets que la columna `label` contiene dos clases. Las clases se denominan `not_equivalent` y `equivalent`. Las etiquetas se almacenan como enteros en el conjunto de datos. Al recuperar las etiquetas, [ClassLabel.int2str()](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.ClassLabel.int2str) y [ClassLabel.str2int()](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.ClassLabel.str2int) realizan la conversión del valor entero al nombre de la etiqueta, y viceversa.

Si el tipo de datos contiene una lista de objetos, entonces debe utilizar la función [List](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.List). ¿Recuerdas el conjunto de datos SQuAD?

```py
>>> from datasets import load_dataset
>>> dataset = load_dataset('rajpurkar/squad', split='train')
>>> dataset.features
{'id': Value('string'),
 'title': Value('string'),
 'context': Value('string'),
 'question': Value('string'),
 'answers': {'text': List(Value('string')),
  'answer_start': List(Value('int32'))}}
```

El campo `answers` se construye usando el diccionario de características porque y contiene dos subcampos, `text` y `answer_start`, que son listas de `string` y `int32`, respectivamente.

> [!TIP]
> Consulte la sección [flatten](./process#flatten) para aprender cómo puede extraer los subcampos anidados como columnas independientes.

El tipo de característica de array es útil para crear matrices de varios tamaños. Puede crear matrices de dos dimensiones con [Array2D](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Array2D) e incluso matrices de cinco dimensiones con [Array5D](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Array5D).

```py
>>> features = Features({'a': Array2D(shape=(1, 3), dtype='int32')})
```

El tipo de matriz también permite que la primera dimensión de la matriz sea dinámica. Esto resulta útil para manejar secuencias de longitudes variables, como oraciones, sin necesidad de rellenar o truncar la entrada para adaptarla a una forma uniforme.

```py
>>> features = Features({'a': Array3D(shape=(None, 5, 2), dtype='int32')})
```

## Característica de audio

Los conjuntos de datos de audio tienen una columna de tipo [Audio](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Audio), que contiene tres campos importantes:

- `array`: los datos de audio decodificados representados como un array unidimensional.
- `path`: la ruta del archivo de audio descargado.
- `sampling_rate`: la tasa de muestreo de los datos de audio.

Al cargar un conjunto de datos de audio y llamar a la columna de audio, la característica [Audio](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Audio) decodifica y re-muestrea automáticamente el archivo de audio:

```py
>>> from datasets import load_dataset, Audio

>>> dataset = load_dataset("PolyAI/minds14", "en-US", split="train")
>>> dataset[0]["audio"]
<datasets.features._torchcodec.AudioDecoder object at 0x11642b6a0>
```

> [!WARNING]
> Índice en un conjunto de datos de audio usando primero el índice de fila y luego la columna `audio` - `dataset[0]["audio"]` - para evitar decodificar y re-muestrear todos los archivos de audio del conjunto de datos. De lo contrario, este puede ser un proceso lento y que consume mucho tiempo si tiene un conjunto de datos grande.

Con `decode=False`, el tipo [Audio](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Audio) simplemente te proporciona la ruta o los bytes del archivo de audio, sin decodificarlo en un objeto `AudioDecoder` de torchcodec,

```py
>>> dataset = load_dataset("PolyAI/minds14", "en-US", split="train").cast_column("audio", Audio(decode=False))
>>> dataset[0]
{'audio': {'bytes': None,
  'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav'},
 'english_transcription': 'I would like to set up a joint account with my partner',
 'intent_class': 11,
 'lang_id': 4,
 'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav',
 'transcription': 'I would like to set up a joint account with my partner'}
```

## Característica de imagen

Los conjuntos de datos de imágenes tienen una columna de tipo [Image](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Image), que carga objetos `PIL.Image` a partir de imágenes almacenadas como bytes:

Al cargar un conjunto de datos de imágenes y llamar a la columna de imágenes, la característica [Image](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Image) decodifica automáticamente el archivo de imagen:

```py
>>> from datasets import load_dataset, Image

>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train")
>>> dataset[0]["image"]
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=500x500 at 0x125506CF8>
```

> [!WARNING]
> Índice en un conjunto de datos de imágenes usando primero el índice de fila y luego la columna `image` - `dataset[0]["image"]` - para evitar decodificar todos los archivos de imagen del conjunto de datos. De lo contrario, este puede ser un proceso lento y que consume mucho tiempo si tiene un conjunto de datos grande.

Con `decode=False`, el tipo [Image](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Image) simplemente te proporciona la ruta o los bytes del archivo de imagen, sin decodificarlo en un `PIL.Image`,

```py
>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train").cast_column("image", Image(decode=False))
>>> dataset[0]["image"]
{'bytes': None,
 'path': '/Users/username/.cache/huggingface/datasets/downloads/extracted/772e7c1fba622cff102b85dd74bcce46e8168634df4eaade7bedd3b8d91d3cd7/train/healthy/healthy_train.265.jpg'}
```

Dependiendo del conjunto de datos, es posible que obtenga la ruta de la imagen descargada localmente, o el contenido de la imagen en bytes si el conjunto de datos no está compuesto por archivos individuales.

También puede definir un conjunto de datos de imágenes a partir de matrices de numpy:

```python
>>> ds = Dataset.from_dict({"i": [np.zeros(shape=(16, 16, 3), dtype=np.uint8)]}, features=Features({"i": Image()}))
```

Y en este caso, los arrays de numpy se codifican en PNG (o en TIFF si la precisión de los valores de píxeles es importante).

Para matrices de múltiples canales, como RGB o RGBA, solo se admite uint8. Si usas una precisión mayor, se muestra una advertencia y la matriz se convierte a uint8. Para imágenes en escala de grises, puedes usar la precisión de enteros o flotantes que desees, siempre que sea compatible con `Pillow`. Se muestra una advertencia si la precisión de enteros o flotantes de tu imagen es demasiado alta, y en ese caso la matriz se convierte a un tipo de menor precisión: una matriz int64 se convierte a int32, y una matriz float64 se convierte a float32.

## Característica de malla

Los conjuntos de datos de malla tienen una columna de tipo [Mesh](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Mesh), que carga archivos de malla 3D como objetos `trimesh`.

Al cargar un conjunto de datos de mallas y llamar a la columna de mallas, la característica [Mesh](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Mesh) decodifica automáticamente el archivo de malla:

```py
>>> from datasets import load_dataset, Mesh

>>> dataset = load_dataset("VINAY-UMRETHE/My-Mesh-Dataset", split="train")
>>> dataset[0]["mesh"]
<trimesh.Scene(len(geometry)=33)>
```

Según el contenido del archivo, `trimesh` puede devolver un objeto `trimesh.Trimesh` o un objeto `trimesh.Scene`.

> [!WARNING]
> Índice en un conjunto de datos de malla usando primero el índice de fila y luego la columna `mesh` - `dataset[0]["mesh"]` - para evitar decodificar todos los archivos de malla del conjunto de datos. De lo contrario, este puede ser un proceso lento y que consume mucho tiempo si se tiene un conjunto de datos grande.

Con `decode=False`, el tipo [Mesh](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Mesh) te proporciona la ruta o los bytes del archivo de malla sin decodificarlo con `trimesh`:

```py
>>> dataset = load_dataset("VINAY-UMRETHE/My-Mesh-Dataset", split="train").cast_column("mesh", Mesh(decode=False))
>>> dataset[0]["mesh"]
{'bytes': b'...',
 'path': '00001.glb'}
```

La función [Mesh](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Mesh) admite archivos `.glb`, `.gltf`, `.ply` y `.stl`. Para los bytes incrustados, se utiliza la `path` almacenada para inferir el tipo de archivo de malla.

## Característica Json

Los datasets se basan en Arrow, un formato columnar, y por lo tanto esperan que cada ejemplo tenga el mismo tipo y subtipos, y que los diccionarios tengan las mismas claves y tipos de valores. Al cargar un dataset, se produce un error si los campos tienen tipos que no coinciden, y se rellenan los campos faltantes en los diccionarios con None para que todos los diccionarios tengan las mismas claves y tipos de valores.

Para evitar esto y permitir tipos mixtos sin errores, puede usar `on_mixed_types="use_json"` o especificar `features=` con un tipo [Json](/docs/datasets/v5.2.0/es/package_reference/loading_methods#datasets.Json):

```python
>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]})
Traceback (most recent call last):
  ...
  File "pyarrow/error.pxi", line 92, in pyarrow.lib.check_status
pyarrow.lib.ArrowInvalid: Could not convert 'foo' with type str: tried to convert to int64

>>> features = Features({"a": Json()})
>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]}, features=features)
>>> ds.features
{'a': Json()}
>>> list(ds["a"])
[0, "foo", {"subfield": "bar"}]
```

También es útil para listas de diccionarios con claves y valores arbitrarios, para evitar rellenar los campos que faltan con None:

```python
>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]})
>>> ds.features
{'a': List({'b': Value('int64'), 'c': Value('int64')})}
>>> list(ds["a"])
[[{'b': 0, 'c': None}, {'b': None, 'c': 0}]]  # missing fields are filled with None

>>> features = Features({"a": List(Json())})
>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]}, features=features)
>>> ds.features
{'a': List(Json())}
>>> list(ds["a"])
[[{'b': 0}, {'c': 0}]]  # OK
```

Otro ejemplo con datos de llamadas a herramientas y el argumento `on_mixed_types="use_json"` (útil para no tener que especificar `features=` manualmente):

```python
>>> messages = [
...     {"role": "user", "content": "Turn on the living room lights and play my electronic music playlist."},
...     {"role": "assistant", "tool_calls": [
...         {"type": "function", "function": {
...             "name": "control_light",
...             "arguments": {"room": "living room", "state": "on"}
...         }},
...         {"type": "function", "function": {
...             "name": "play_music",
...             "arguments": {"playlist": "electronic"}  # mixed-type here since keys ["playlist"] and ["room", "state"] are different
...         }}]
...     },
...     {"role": "tool", "name": "control_light", "content": "The lights in the living room are now on."},
...     {"role": "tool", "name": "play_music", "content": "The music is now playing."},
...     {"role": "assistant", "content": "Done!"}
... ]
>>> ds = Dataset.from_dict({"messages": [messages]}, on_mixed_types="use_json")
>>> ds.features
{'messages': List({'role': Value('string'), 'content': Value('string'), 'tool_calls': List(Json()), 'name': Value('string')})}
>>> ds[0][1]["tool_calls"][0]["function"]["arguments"]
{"room": "living room", "state": "on"}
```

