# Quy trình

🤗 Datasets cung cấp nhiều công cụ để thay đổi cấu trúc và nội dung của một dataset. Các công cụ này rất quan trọng để dọn dẹp dataset, tạo thêm các cột, chuyển đổi giữa các feature và định dạng, và nhiều hơn nữa.

Hướng dẫn này sẽ cho bạn thấy cách:

- Sắp xếp lại các hàng và chia bộ dữ liệu.
- Đổi tên và xóa các cột, cùng các thao tác cột phổ biến khác.
- Áp dụng các hàm xử lý cho từng ví dụ trong một tập dữ liệu.
- Nối các bộ dữ liệu.
- Áp dụng một phép biến đổi định dạng tùy chỉnh.
- Lưu và xuất các bộ dữ liệu đã xử lý.

Để biết thêm chi tiết cụ thể về việc xử lý các chế độ dữ liệu khác, hãy xem hướng dẫn xử lý tập dữ liệu âm thanh, hướng dẫn xử lý tập dữ liệu hình ảnh hoặc hướng dẫn xử lý tập dữ liệu văn bản.

Các ví dụ trong hướng dẫn này sử dụng bộ dữ liệu MRPC, nhưng bạn có thể tự do tải bất kỳ bộ dữ liệu nào bạn muốn và làm theo!

```py
>>> from datasets import load_dataset
>>> dataset = load_dataset("nyu-mll/glue", "mrpc", split="train")
```

> [!WARNING]
> Tất cả các phương thức xử lý trong hướng dẫn này đều trả về một đối tượng [Dataset](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset) mới. Việc sửa đổi không được thực hiện tại chỗ. Hãy cẩn thận khi ghi đè lên dataset trước đó của bạn!

## Sắp xếp, xáo trộn, chọn, tách và chia

Có một số hàm để sắp xếp lại cấu trúc của một dataset. Các hàm này hữu ích để chỉ chọn các dòng bạn muốn, tạo các phần chia train và test, và chia nhỏ các dataset rất lớn thành các phần nhỏ hơn.

### Sắp xếp

Sử dụng [sort()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.sort) để sắp xếp các giá trị trong cột theo giá trị số của chúng. Cột được cung cấp phải tương thích với NumPy.

```py
>>> dataset["label"][:10]
[1, 0, 1, 0, 1, 1, 0, 1, 0, 0]
>>> sorted_dataset = dataset.sort("label")
>>> sorted_dataset["label"][:10]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> sorted_dataset["label"][-10:]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
```

Bên trong, thao tác này tạo ra một danh sách các chỉ số được sắp xếp theo giá trị của cột. Bản ánh xạ chỉ số này sau đó được dùng để truy cập các hàng tương ứng trong bảng Arrow bên dưới.

### Xáo trộn

Hàm [shuffle()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.shuffle) sắp xếp lại ngẫu nhiên các giá trị trong cột. Bạn có thể chỉ định tham số `generator` trong hàm này để sử dụng một `numpy.random.Generator` khác nếu bạn muốn kiểm soát nhiều hơn thuật toán được dùng để xáo trộn bộ dữ liệu.

```py
>>> shuffled_dataset = sorted_dataset.shuffle(seed=42)
>>> shuffled_dataset["label"][:10]
[1, 1, 1, 0, 1, 1, 1, 1, 1, 0]
```

Shuffling lấy danh sách các chỉ số `[0:len(my_dataset)]` và xáo trộn nó để tạo ra một ánh xạ chỉ số. Tuy nhiên, ngay khi [Dataset](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset) của bạn có một ánh xạ chỉ số, tốc độ có thể chậm đi 10 lần. Điều này là do có một bước bổ sung để lấy chỉ số hàng cần đọc bằng cách sử dụng ánh xạ chỉ số, và quan trọng nhất là bạn không còn đọc các khối dữ liệu liên tục nữa. Để khôi phục tốc độ, bạn cần ghi đè lại toàn bộ dataset trên đĩa của mình bằng cách sử dụng [Dataset.flatten_indices()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.flatten_indices), hàm này sẽ loại bỏ ánh xạ chỉ số. Hoặc, bạn có thể chuyển sang [IterableDataset](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.IterableDataset) và tận dụng tính năng xáo trộn gần đúng nhanh của nó [IterableDataset.shuffle()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.IterableDataset.shuffle):

```py
>>> iterable_dataset = dataset.to_iterable_dataset(num_shards=128)
>>> shuffled_iterable_dataset = iterable_dataset.shuffle(seed=42, buffer_size=1000)
```

### Chọn và Lọc

Có hai tùy chọn để lọc các dòng trong một tập dữ liệu: [select()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.select) và [filter()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.filter).

- [select()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.select) trả về các hàng theo một danh sách các chỉ số:

```py
>>> small_dataset = dataset.select([0, 10, 20, 30, 40, 50])
>>> len(small_dataset)
6
```

- [filter()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.filter) trả về các dòng khớp với điều kiện được chỉ định:

```py
>>> start_with_ar = dataset.filter(lambda example: example["sentence1"].startswith("Ar"))
>>> len(start_with_ar)
6
>>> start_with_ar["sentence1"]
['Around 0335 GMT , Tab shares were up 19 cents , or 4.4 % , at A $ 4.56 , having earlier set a record high of A $ 4.57 .',
'Arison said Mann may have been one of the pioneers of the world music movement and he had a deep love of Brazilian music .',
'Arts helped coach the youth on an eighth-grade football team at Lombardi Middle School in Green Bay .',
'Around 9 : 00 a.m. EDT ( 1300 GMT ) , the euro was at $ 1.1566 against the dollar , up 0.07 percent on the day .',
"Arguing that the case was an isolated example , Canada has threatened a trade backlash if Tokyo 's ban is not justified on scientific grounds .",
'Artists are worried the plan would harm those who need help most - performers who have a difficult time lining up shows .'
]
```

[filter()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.filter) cũng có thể lọc theo chỉ số nếu bạn đặt `with_indices=True`:

```py
>>> even_dataset = dataset.filter(lambda example, idx: idx % 2 == 0, with_indices=True)
>>> len(even_dataset)
1834
>>> len(dataset) / 2
1834.0
```

Trừ khi danh sách các chỉ số cần giữ là liên tục, các phương pháp đó cũng tạo ra một ánh xạ chỉ số bên trong.

### Tách

Hàm [train_test_split()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.train_test_split) tạo ra các tập huấn luyện và kiểm tra nếu bộ dữ liệu của bạn chưa có sẵn. Điều này cho phép bạn điều chỉnh tỷ lệ tương đối hoặc số lượng mẫu tuyệt đối trong mỗi tập. Trong ví dụ bên dưới, hãy sử dụng tham số `test_size` để tạo một tập kiểm tra chiếm 10% bộ dữ liệu gốc:

```py
>>> dataset.train_test_split(test_size=0.1)
{'train': Dataset(schema: {'sentence1': 'string', 'sentence2': 'string', 'label': 'int64', 'idx': 'int32'}, num_rows: 3301),
'test': Dataset(schema: {'sentence1': 'string', 'sentence2': 'string', 'label': 'int64', 'idx': 'int32'}, num_rows: 367)}
>>> 0.1 * len(dataset)
366.8
```

Các phần chia (splits) được xáo trộn (shuffle) theo mặc định, nhưng bạn có thể đặt `shuffle=False` để ngăn việc xáo trộn.

### Shard

🤗 Datasets hỗ trợ sharding để chia một dataset rất lớn thành một số lượng chunk đã định trước. Chỉ định tham số `num_shards` trong [shard()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.shard) để xác định số shard cần chia dataset thành. Bạn cũng cần cung cấp shard muốn trả về bằng tham số `index`.

Ví dụ, bộ dữ liệu [stanfordnlp/imdb](https://huggingface.co/datasets/stanfordnlp/imdb) có 25000 ví dụ:

```py
>>> from datasets import load_dataset
>>> dataset = load_dataset("stanfordnlp/imdb", split="train")
>>> print(dataset)
Dataset({
    features: ['text', 'label'],
    num_rows: 25000
})
```

Sau khi chia bộ dữ liệu thành bốn phần, phần đầu tiên sẽ chỉ có 6250 ví dụ:

```py
>>> dataset.shard(num_shards=4, index=0)
Dataset({
    features: ['text', 'label'],
    num_rows: 6250
})
>>> print(25000/4)
6250.0
```

## Đổi tên, xóa, chuyển kiểu và làm phẳng

Các hàm sau cho phép bạn sửa đổi các cột của một dataset. Những hàm này hữu ích để đổi tên hoặc xóa các cột, thay đổi các cột thành một tập hợp các đặc trưng mới, và làm phẳng các cấu trúc cột lồng nhau.

### Đổi tên

Sử dụng [rename_column()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.rename_column) khi bạn cần đổi tên một cột trong dataset của mình. Các đặc trưng (features) liên quan đến cột gốc thực chất được chuyển sang dưới tên cột mới, thay vì chỉ thay thế cột gốc tại chỗ.

Cung cấp cho [rename_column()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.rename_column) tên của cột gốc và tên cột mới:

```py
>>> dataset
Dataset({
    features: ['sentence1', 'sentence2', 'label', 'idx'],
    num_rows: 3668
})
>>> dataset = dataset.rename_column("sentence1", "sentenceA")
>>> dataset = dataset.rename_column("sentence2", "sentenceB")
>>> dataset
Dataset({
    features: ['sentenceA', 'sentenceB', 'label', 'idx'],
    num_rows: 3668
})
```

### Xóa

Khi cần xóa một hoặc nhiều cột, hãy cung cấp tên cột cần xóa cho hàm [remove_columns()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.remove_columns). Để xóa nhiều hơn một cột, hãy cung cấp một danh sách các tên cột:

```py
>>> dataset = dataset.remove_columns("label")
>>> dataset
Dataset({
    features: ['sentence1', 'sentence2', 'idx'],
    num_rows: 3668
})
>>> dataset = dataset.remove_columns(["sentence1", "sentence2"])
>>> dataset
Dataset({
    features: ['idx'],
    num_rows: 3668
})
```

Ngược lại, [select_columns()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.select_columns) chọn một hoặc nhiều cột cần giữ lại và xóa các cột còn lại. Hàm này nhận một tên cột hoặc một danh sách các tên cột:

```py
>>> dataset
Dataset({
    features: ['sentence1', 'sentence2', 'label', 'idx'],
    num_rows: 3668
})
>>> dataset = dataset.select_columns(['sentence1', 'sentence2', 'idx'])
>>> dataset
Dataset({
    features: ['sentence1', 'sentence2', 'idx'],
    num_rows: 3668
})
>>> dataset = dataset.select_columns('idx')
>>> dataset
Dataset({
    features: ['idx'],
    num_rows: 3668
})
```

### Cast

Hàm [cast()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.cast) chuyển đổi kiểu đặc trưng của một hoặc nhiều cột. Hàm này nhận [Features](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Features) mới của bạn làm đối số. Ví dụ dưới đây minh họa cách thay đổi các đặc trưng [ClassLabel](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.ClassLabel) và [Value](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Value):

```py
>>> dataset.features
{'sentence1': Value('string'),
'sentence2': Value('string'),
'label': ClassLabel(names=['not_equivalent', 'equivalent']),
'idx': Value('int32')}

>>> from datasets import ClassLabel, Value
>>> new_features = dataset.features.copy()
>>> new_features["label"] = ClassLabel(names=["negative", "positive"])
>>> new_features["idx"] = Value("int64")
>>> dataset = dataset.cast(new_features)
>>> dataset.features
{'sentence1': Value('string'),
'sentence2': Value('string'),
'label': ClassLabel(names=['negative', 'positive']),
'idx': Value('int64')}
```

> [!TIP]
> Casting chỉ hoạt động nếu kiểu đặc trưng gốc và kiểu đặc trưng mới tương thích. Ví dụ, bạn có thể cast một cột có kiểu đặc trưng `Value("int32")` thành `Value("bool")` nếu cột gốc chỉ chứa các giá trị một và không.

Sử dụng hàm [cast_column()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.cast_column) để thay đổi kiểu đặc trưng của một cột duy nhất. Truyền tên cột và kiểu đặc trưng mới của nó dưới dạng các đối số:

```py
>>> dataset.features
{'audio': Audio(sampling_rate=44100, mono=True)}

>>> dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))
>>> dataset.features
{'audio': Audio(sampling_rate=16000, mono=True)}
```

### Dàn phẳng

Đôi khi một cột có thể là một cấu trúc lồng nhau của nhiều kiểu dữ liệu. Hãy xem cấu trúc lồng nhau bên dưới từ bộ dữ liệu 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'))}}
```

Trường `answers` chứa hai trường con: `text` và `answer_start`. Sử dụng hàm [flatten()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.flatten) để trích xuất các trường con thành các cột riêng biệt:

```py
>>> flat_dataset = dataset.flatten()
>>> flat_dataset
Dataset({
    features: ['id', 'title', 'context', 'question', 'answers.text', 'answers.answer_start'],
 num_rows: 87599
})
```

Chú ý rằng các trường con giờ đã là các cột độc lập: `answers.text` và `answers.answer_start`.

## Bản đồ

Một số ứng dụng mạnh mẽ hơn của 🤗 Datasets đến từ việc sử dụng hàm [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map). Mục đích chính của [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) là tăng tốc các hàm xử lý. Nó cho phép bạn áp dụng một hàm xử lý cho từng ví dụ trong bộ dữ liệu, độc lập hoặc theo các lô. Hàm này thậm chí có thể tạo ra các hàng và cột mới.

Trong ví dụ sau, thêm tiền tố `'My sentence: '` cho mỗi giá trị `sentence1` trong bộ dữ liệu.

Bắt đầu bằng cách tạo một hàm thêm `'My sentence: '` vào đầu mỗi câu. Hàm cần nhận và trả về một `dict`:

```py
>>> def add_prefix(example):
...     example["sentence1"] = 'My sentence: ' + example["sentence1"]
...     return example
```

Bây giờ hãy sử dụng [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) để áp dụng hàm `add_prefix` lên toàn bộ tập dữ liệu:

```py
>>> updated_dataset = small_dataset.map(add_prefix)
>>> updated_dataset["sentence1"][:5]
['My sentence: Amrozi accused his brother , whom he called " the witness " , of deliberately distorting his evidence .',
"My sentence: Yucaipa owned Dominick 's before selling the chain to Safeway in 1998 for $ 2.5 billion .",
'My sentence: They had published an advertisement on the Internet on June 10 , offering the cargo for sale , he added .',
'My sentence: Around 0335 GMT , Tab shares were up 19 cents , or 4.4 % , at A $ 4.56 , having earlier set a record high of A $ 4.57 .',
]
```

Hãy xem một ví dụ khác, lần này bạn sẽ xóa một cột bằng [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map). Khi bạn xóa một cột, nó chỉ bị xóa sau khi ví dụ đã được cung cấp cho hàm được map. Điều này cho phép hàm được map sử dụng nội dung của các cột trước khi chúng bị xóa.

Chỉ định cột cần xóa bằng tham số `remove_columns` trong [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map):

```py
>>> updated_dataset = dataset.map(lambda example: {"new_sentence": example["sentence1"]}, remove_columns=["sentence1"])
>>> updated_dataset.column_names
['sentence2', 'label', 'idx', 'new_sentence']
```

> [!TIP]
> 🤗 Datasets cũng có hàm [remove_columns()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.remove_columns) nhanh hơn vì nó không sao chép dữ liệu của các cột còn lại.

Bạn cũng có thể sử dụng [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) với các chỉ số nếu bạn đặt `with_indices=True`. Ví dụ bên dưới thêm chỉ số vào đầu mỗi câu:

```py
>>> updated_dataset = dataset.map(lambda example, idx: {"sentence2": f"{idx}: " + example["sentence2"]}, with_indices=True)
>>> updated_dataset["sentence2"][:5]
['0: Referring to him as only " the witness " , Amrozi accused his brother of deliberately distorting his evidence .',
 "1: Yucaipa bought Dominick 's in 1995 for $ 693 million and sold it to Safeway for $ 1.8 billion in 1998 .",
 "2: On June 10 , the ship 's owners had published an advertisement on the Internet , offering the explosives for sale .",
 '3: Tab shares jumped 20 cents , or 4.6 % , to set a record closing high at A $ 4.57 .',
 '4: PG & E Corp. shares jumped $ 1.63 or 8 percent to $ 21.03 on the New York Stock Exchange on Friday .'
]
```

### Xử lý đa tiến trình

Multiprocessing tăng tốc đáng kể quá trình xử lý bằng cách song song hóa các tiến trình trên CPU. Đặt tham số `num_proc` trong [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) để xác định số lượng tiến trình cần sử dụng:

```py
>>> updated_dataset = dataset.map(lambda example, idx: {"sentence2": f"{idx}: " + example["sentence2"]}, with_indices=True, num_proc=4)
```

[map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) cũng hoạt động với rank của tiến trình nếu bạn đặt `with_rank=True`. Điều này tương tự như tham số `with_indices`. Tham số `with_rank` trong hàm được ánh xạ sẽ đứng sau tham số `index` nếu tham số đó đã có mặt.

```py
>>> import torch
>>> from multiprocess import set_start_method
>>> from transformers import AutoTokenizer, AutoModelForCausalLM
>>> from datasets import load_dataset
>>>
>>> # Get an example dataset
>>> dataset = load_dataset("fka/awesome-chatgpt-prompts", split="train")
>>>
>>> # Get an example model and its tokenizer
>>> model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen1.5-0.5B-Chat").eval()
>>> tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen1.5-0.5B-Chat")
>>>
>>> def gpu_computation(batch, rank):
...     # Move the model on the right GPU if it's not there already
...     device = f"cuda:{(rank or 0) % torch.cuda.device_count()}"
...     model.to(device)
...
...     # Your big GPU call goes here, for example:
...     chats = [[
...         {"role": "system", "content": "You are a helpful assistant."},
...         {"role": "user", "content": prompt}
...     ] for prompt in batch["prompt"]]
...     texts = [tokenizer.apply_chat_template(
...         chat,
...         tokenize=False,
...         add_generation_prompt=True
...     ) for chat in chats]
...     model_inputs = tokenizer(texts, padding=True, return_tensors="pt").to(device)
...     with torch.no_grad():
...         outputs = model.generate(**model_inputs, max_new_tokens=512)
...     batch["output"] = tokenizer.batch_decode(outputs, skip_special_tokens=True)
...     return batch
>>>
>>> if __name__ == "__main__":
...     set_start_method("spawn")
...     updated_dataset = dataset.map(
...         gpu_computation,
...         batched=True,
...         batch_size=16,
...         with_rank=True,
...         num_proc=torch.cuda.device_count(),  # one process per GPU
...     )
```

Use-case chính của rank là song song hóa tính toán trên nhiều GPU. Điều này yêu cầu thiết lập `multiprocess.set_start_method("spawn")`. Nếu không, bạn sẽ nhận được lỗi CUDA sau:

```bash
RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method.
```

### Xử lý theo lô

Hàm [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) hỗ trợ làm việc với các lô (batch) ví dụ. Thao tác trên các lô bằng cách đặt `batched=True`. Kích thước lô mặc định là 1000, nhưng bạn có thể điều chỉnh bằng tham số `batch_size`. Xử lý theo lô cho phép các ứng dụng thú vị như chia các câu dài thành các đoạn ngắn hơn và tăng cường dữ liệu.

#### Tách các ví dụ dài

Khi các ví dụ quá dài, bạn có thể muốn chia chúng thành nhiều phần nhỏ hơn. Hãy bắt đầu bằng cách tạo một hàm mà:

1. Chia trường `sentence1` thành các đoạn 50 ký tự.

2. Ghép tất cả các phần (chunks) lại với nhau để tạo bộ dữ liệu mới.

```py
>>> def chunk_examples(examples):
...     chunks = []
...     for sentence in examples["sentence1"]:
...         chunks += [sentence[i:i + 50] for i in range(0, len(sentence), 50)]
...     return {"chunks": chunks}
```

Áp dụng hàm bằng [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map):

```py
>>> chunked_dataset = dataset.map(chunk_examples, batched=True, remove_columns=dataset.column_names)
>>> chunked_dataset[:10]
{'chunks': ['Amrozi accused his brother , whom he called " the ',
            'witness " , of deliberately distorting his evidenc',
            'e .',
            "Yucaipa owned Dominick 's before selling the chain",
            ' to Safeway in 1998 for $ 2.5 billion .',
            'They had published an advertisement on the Interne',
            't on June 10 , offering the cargo for sale , he ad',
            'ded .',
            'Around 0335 GMT , Tab shares were up 19 cents , or',
            ' 4.4 % , at A $ 4.56 , having earlier set a record']}
```

Hãy chú ý cách các câu được chia thành các đoạn ngắn hơn, và có nhiều hàng hơn trong bộ dữ liệu.

```py
>>> dataset
Dataset({
 features: ['sentence1', 'sentence2', 'label', 'idx'],
 num_rows: 3668
})
>>> chunked_dataset
Dataset({
    features: ['chunks'],
    num_rows: 10470
})
```

#### Tăng cường dữ liệu

Hàm [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) cũng có thể được sử dụng để tăng cường dữ liệu. Ví dụ sau tạo thêm các từ cho một token bị che trong một câu.

Tải và sử dụng mô hình [RoBERTa](https://huggingface.co/roberta-base) trong [FillMaskPipeline](https://huggingface.co/transformers/main_classes/pipelines#transformers.FillMaskPipeline) của 🤗 Transformers:

```py
>>> from random import randint
>>> from transformers import pipeline

>>> fillmask = pipeline("fill-mask", model="roberta-base")
>>> mask_token = fillmask.tokenizer.mask_token
>>> smaller_dataset = dataset.filter(lambda e, i: i<100, with_indices=True)
```

Tạo một hàm để chọn ngẫu nhiên một từ để che trong câu. Hàm cũng cần trả về câu gốc và hai từ thay thế hàng đầu do RoBERTa tạo ra.

```py
>>> def augment_data(examples):
...     outputs = []
...     for sentence in examples["sentence1"]:
...         words = sentence.split(' ')
...         K = randint(1, len(words)-1)
...         masked_sentence = " ".join(words[:K]  + [mask_token] + words[K+1:])
...         predictions = fillmask(masked_sentence)
...         augmented_sequences = [predictions[i]["sequence"] for i in range(3)]
...         outputs += [sentence] + augmented_sequences
...
...     return {"data": outputs}
```

Sử dụng [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) để áp dụng hàm cho toàn bộ tập dữ liệu:

```py
>>> augmented_dataset = smaller_dataset.map(augment_data, batched=True, remove_columns=dataset.column_names, batch_size=8)
>>> augmented_dataset[:9]["data"]
['Amrozi accused his brother , whom he called " the witness " , of deliberately distorting his evidence .',
 'Amrozi accused his brother, whom he called " the witness ", of deliberately withholding his evidence.',
 'Amrozi accused his brother, whom he called " the witness ", of deliberately suppressing his evidence.',
 'Amrozi accused his brother, whom he called " the witness ", of deliberately destroying his evidence.',
 "Yucaipa owned Dominick 's before selling the chain to Safeway in 1998 for $ 2.5 billion .",
 'Yucaipa owned Dominick Stores before selling the chain to Safeway in 1998 for $ 2.5 billion.',
 "Yucaipa owned Dominick's before selling the chain to Safeway in 1998 for $ 2.5 billion.",
 'Yucaipa owned Dominick Pizza before selling the chain to Safeway in 1998 for $ 2.5 billion.'
]
```

Với mỗi câu gốc, RoBERTA đã bổ sung ba lựa chọn thay thế cho một từ ngẫu nhiên. Từ gốc `distorting` được bổ sung bởi `withholding`, `suppressing` và `destroying`.

### Xử lý bất đồng bộ

Các hàm bất đồng bộ (asynchronous) hữu ích để gọi các điểm cuối API song song, chẳng hạn như để tải xuống nội dung như hình ảnh hoặc gọi một điểm cuối mô hình.

Bạn có thể định nghĩa một hàm bất đồng bộ bằng cách sử dụng từ khóa `async` và `await`, dưới đây là một ví dụ về hàm để gọi một mô hình chat từ Hugging Face:

```python
>>> import aiohttp
>>> import asyncio
>>> from huggingface_hub import get_token
>>> sem = asyncio.Semaphore(20)  # max number of simultaneous queries
>>> async def query_model(model, prompt):
...     api_url = f"/static-proxy?url=https%3A%2F%2Fapi-inference.huggingface.co%2Fmodels%2F%7Bmodel%7D%2Fv1%2Fchat%2Fcompletions"
...     headers = {"Authorization": f"Bearer {get_token()}", "Content-Type": "application/json"}
...     json = {"messages": [{"role": "user", "content": prompt}], "max_tokens": 20, "seed": 42}
...     async with sem, aiohttp.ClientSession() as session, session.post(api_url, headers=headers, json=json) as response:
...         output = await response.json()
...         return {"Output": output["choices"][0]["message"]["content"]}
```

Các hàm bất đồng bộ chạy song song, giúp tăng tốc quy trình đáng kể. Cùng một đoạn mã sẽ mất nhiều thời gian hơn rất nhiều nếu chạy tuần tự, vì nó không làm gì trong khi chờ phản hồi từ mô hình. Nhìn chung, bạn nên sử dụng `async` / `await` khi hàm của bạn phải chờ phản hồi từ một API, chẳng hạn, hoặc khi nó tải dữ liệu và có thể mất một ít thời gian.

Lưu ý sự hiện diện của `Semaphore`: nó đặt ra số lượng tối đa các truy vấn có thể chạy song song. Khuyến nghị sử dụng `Semaphore` khi gọi API để tránh các lỗi giới hạn tần suất (rate limit).

Hãy sử dụng nó để gọi mô hình [microsoft/Phi-3-mini-4k-instruct](https://huggingface.co/microsoft/Phi-3-mini-4k-instruct) và yêu cầu nó trả về chủ đề chính của từng bài toán trong bộ dữ liệu [Maxwell-Jia/AIME_2024](https://huggingface.co/Maxwell-Jia/AIME_2024):

````python
>>> from datasets import load_dataset
>>> ds = load_dataset("Maxwell-Jia/AIME_2024", split="train")
>>> model = "microsoft/Phi-3-mini-4k-instruct"
>>> prompt = 'What is this text mainly about ? Here is the text:\n\n```\n{Problem}\n```\n\nReply using one or two words max, e.g. "The main topic is Linear Algebra".'
>>> async def get_topic(example):
...     return await query_model(model, prompt.format(Problem=example['Problem']))
>>> ds = ds.map(get_topic)
>>> ds[0]
{'ID': '2024-II-4',
 'Problem': 'Let $x,y$ and $z$ be positive real numbers that...',
 'Solution': 'Denote $\\log_2(x) = a$, $\\log_2(y) = b$, and...,
 'Answer': 33,
 'Output': 'The main topic is Logarithms.'}
````

Ở đây, [Dataset.map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) chạy nhiều hàm `get_topic` bất đồng bộ để không phải chờ từng phản hồi của mô hình, điều sẽ mất rất nhiều thời gian nếu thực hiện tuần tự.

Mặc định, [Dataset.map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) chạy tối đa một nghìn hàm map song song, vì vậy đừng quên đặt số lượng tối đa các cuộc gọi API có thể chạy song song bằng `Semaphore`, nếu không mô hình có thể trả về lỗi giới hạn tần suất hoặc quá tải. Đối với các trường hợp sử dụng nâng cao, bạn có thể thay đổi số lượng truy vấn song song tối đa trong `datasets.config`.

### Xử lý nhiều phần chia

Nhiều dataset có các split có thể được xử lý đồng thời bằng [DatasetDict.map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.DatasetDict.map). Ví dụ, tokenize trường `sentence1` trong split train và test bằng cách:

```py
>>> from datasets import load_dataset

# load all the splits
>>> dataset = load_dataset('nyu-mll/glue', 'mrpc')
>>> encoded_dataset = dataset.map(lambda examples: tokenizer(examples["sentence1"]), batched=True)
>>> encoded_dataset["train"][0]
{'sentence1': 'Amrozi accused his brother , whom he called " the witness " , of deliberately distorting his evidence .',
'sentence2': 'Referring to him as only " the witness " , Amrozi accused his brother of deliberately distorting his evidence .',
'label': 1,
'idx': 0,
'input_ids': [  101,  7277,  2180,  5303,  4806,  1117,  1711,   117,  2292, 1119,  1270,   107,  1103,  7737,   107,   117,  1104,  9938, 4267, 12223, 21811,  1117,  2554,   119,   102],
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
}
```

### Sử dụng phân tán

Khi bạn sử dụng [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) trong môi trường phân tán, bạn cũng nên sử dụng [torch.distributed.barrier](https://pytorch.org/docs/stable/distributed?highlight=barrier#torch.distributed.barrier). Điều này đảm bảo tiến trình chính thực hiện ánh xạ, trong khi các tiến trình khác tải kết quả, từ đó tránh việc thực hiện trùng lặp.

Ví dụ sau cho thấy cách bạn có thể sử dụng `torch.distributed.barrier` để đồng bộ hóa các tiến trình:

```py
>>> from datasets import Dataset
>>> import torch.distributed

>>> dataset1 = Dataset.from_dict({"a": [0, 1, 2]})

>>> if training_args.local_rank > 0:
...     print("Waiting for main process to perform the mapping")
...     torch.distributed.barrier()

>>> dataset2 = dataset1.map(lambda x: {"a": x["a"] + 1})

>>> if training_args.local_rank == 0:
...     print("Loading results from main process")
...     torch.distributed.barrier()
```

## Batch

Phương thức `batch()` cho phép bạn nhóm các mẫu từ tập dữ liệu thành các lô. Điều này đặc biệt hữu ích khi bạn muốn tạo các lô dữ liệu để huấn luyện hoặc đánh giá, nhất là khi làm việc với các mô hình học sâu.

Dưới đây là một ví dụ về cách sử dụng phương thức `batch()`:

```python
>>> from datasets import load_dataset
>>> dataset = load_dataset("cornell-movie-review-data/rotten_tomatoes", split="train")
>>> batched_dataset = dataset.batch(batch_size=4)
>>> batched_dataset[0]
{'text': ['the rock is destined to be the 21st century\'s new " conan " and that he\'s going to make a splash even greater than arnold schwarzenegger , jean-claud van damme or steven segal .',
        'the gorgeously elaborate continuation of " the lord of the rings " trilogy is so huge that a column of words cannot adequately describe co-writer/director peter jackson\'s expanded vision of j . r . r . tolkien\'s middle-earth .',
        'effective but too-tepid biopic',
        'if you sometimes like to go to the movies to have fun , wasabi is a good place to start .'],
'label': [1, 1, 1, 1]}
```

Phương thức `batch()` chấp nhận các tham số sau:

- `batch_size` (`int`): Số lượng mẫu trong mỗi batch.
- `drop_last_batch` (`bool`, mặc định là `False`): Xác định có loại bỏ lô cuối cùng không hoàn chỉnh hay không nếu kích thước bộ dữ liệu không chia hết cho kích thước lô.
- `num_proc` (`int`, tùy chọn, mặc định là `None`): Số lượng tiến trình để sử dụng cho đa tiến trình. Nếu là None, sẽ không sử dụng đa tiến trình. Điều này có thể tăng tốc đáng kể việc tạo batch cho các bộ dữ liệu lớn.

Lưu ý rằng `Dataset.batch()` trả về một [Dataset](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset) mới, trong đó mỗi phần tử là một batch gồm nhiều mẫu từ dataset gốc. Nếu bạn muốn xử lý dữ liệu theo batch, bạn nên sử dụng [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) dạng batch trực tiếp, trong đó một hàm được áp dụng lên các batch nhưng dataset đầu ra không ở dạng batch.

## Nối

Các tập dữ liệu riêng biệt có thể được nối với nhau nếu chúng có cùng kiểu cột. Nối các tập dữ liệu bằng [concatenate_datasets()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.concatenate_datasets):

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

>>> stories = load_dataset("ajibawa-2023/General-Stories-Collection", split="train")
>>> stories = stories.select_columns(["text"])  # only keep the 'text' column
>>> wiki = load_dataset("wikimedia/wikipedia", "20231101.en", split="train")
>>> wiki = wiki.select_columns(["text"])  # only keep the 'text' column

>>> assert stories.features.type == wiki.features.type
>>> bert_dataset = concatenate_datasets([stories, wiki])
```

Bạn cũng có thể nối hai dataset theo chiều ngang bằng cách đặt `axis=1` miễn là các dataset có cùng số dòng:

```py
>>> from datasets import Dataset
>>> stories_ids = Dataset.from_dict({"ids": list(range(len(stories)))})
>>> stories_with_ids = concatenate_datasets([stories, stories_ids], axis=1)
```

### Xen kẽ

Bạn cũng có thể trộn lẫn nhiều tập dữ liệu với nhau bằng cách lấy các ví dụ xen kẽ từ từng tập để tạo thành một tập dữ liệu mới. Cách này được gọi là _interleaving_, được thực hiện bằng hàm [interleave_datasets()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.interleave_datasets). Cả [interleave_datasets()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.interleave_datasets) và [concatenate_datasets()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.concatenate_datasets) đều hoạt động với các đối tượng [Dataset](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset) và [IterableDataset](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.IterableDataset) thông thường. Tham khảo hướng dẫn về [Stream](./stream#interleave) để xem ví dụ về cách interleave các đối tượng [IterableDataset](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.IterableDataset).

Bạn có thể xác định xác suất lấy mẫu cho từng bộ dữ liệu gốc để chỉ định cách xen kẽ các bộ dữ liệu. Trong trường hợp này, bộ dữ liệu mới được xây dựng bằng cách lấy các ví dụ lần lượt từ một bộ dữ liệu ngẫu nhiên cho đến khi một trong các bộ dữ liệu hết mẫu.

```py
>>> from datasets import Dataset, interleave_datasets
>>> seed = 42
>>> probabilities = [0.3, 0.5, 0.2]
>>> d1 = Dataset.from_dict({"a": [0, 1, 2]})
>>> d2 = Dataset.from_dict({"a": [10, 11, 12, 13]})
>>> d3 = Dataset.from_dict({"a": [20, 21, 22]})
>>> dataset = interleave_datasets([d1, d2, d3], probabilities=probabilities, seed=seed)
>>> dataset["a"]
[10, 11, 20, 12, 0, 21, 13]
```

Bạn cũng có thể chỉ định `stopping_strategy`. Chiến lược mặc định, `first_exhausted`, là chiến lược lấy mẫu con, tức là việc xây dựng tập dữ liệu sẽ dừng lại ngay khi một trong các tập dữ liệu hết mẫu. Bạn có thể chỉ định `stopping_strategy=all_exhausted` để thực thi chiến lược lấy mẫu quá mức. Trong trường hợp này, việc xây dựng tập dữ liệu sẽ dừng lại ngay khi mọi mẫu trong mọi tập dữ liệu đã được thêm vào ít nhất một lần. Trên thực tế, điều này có nghĩa là nếu một tập dữ liệu bị cạn, nó sẽ quay lại đầu tập dữ liệu đó cho đến khi đạt được tiêu chí dừng. Lưu ý rằng nếu không chỉ định xác suất lấy mẫu, tập dữ liệu mới sẽ có `max_length_datasets*nb_dataset samples`. Ngoài ra còn có `stopping_strategy=all_exhausted_without_replacement` để đảm bảo rằng mỗi mẫu được xem đúng một lần.

```py
>>> d1 = Dataset.from_dict({"a": [0, 1, 2]})
>>> d2 = Dataset.from_dict({"a": [10, 11, 12, 13]})
>>> d3 = Dataset.from_dict({"a": [20, 21, 22]})
>>> dataset = interleave_datasets([d1, d2, d3], stopping_strategy="all_exhausted")
>>> dataset["a"]
[0, 10, 20, 1, 11, 21, 2, 12, 22, 0, 13, 20]
```

## Định dạng

Hàm [with_format()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.with_format) thay đổi định dạng của một cột để tương thích với một số định dạng dữ liệu phổ biến. Chỉ định đầu ra mong muốn trong tham số `type`. Bạn cũng có thể chọn các cột cần định dạng bằng cách sử dụng `columns=`. Việc định dạng được áp dụng theo thời gian thực.

Ví dụ, tạo các tensor PyTorch bằng cách đặt `type="torch"`:

```py
>>> dataset = dataset.with_format(type="torch")
```

Hàm [set_format()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.set_format) cũng thay đổi định dạng của một cột, ngoại trừ việc nó chạy tại chỗ:

```py
>>> dataset.set_format(type="torch")
```

Nếu bạn cần đặt lại bộ dữ liệu về định dạng ban đầu, hãy đặt format thành `None` (hoặc sử dụng [reset_format()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.reset_format)):

```py
>>> dataset.format
{'type': 'torch', 'format_kwargs': {}, 'columns': [...], 'output_all_columns': False}
>>> dataset = dataset.with_format(None)
>>> dataset.format
{'type': None, 'format_kwargs': {}, 'columns': [...], 'output_all_columns': False}
```

### Định dạng Tensors

Nhiều định dạng tensor hoặc mảng được hỗ trợ. Về mặt chung, việc sử dụng các định dạng này được khuyến nghị thay vì tự động chuyển đổi đầu ra của một dataset sang tensor hoặc mảng, nhằm tránh các bản sao dữ liệu không cần thiết và tăng tốc quá trình nạp dữ liệu.

Dưới đây là danh sách các định dạng tensor hoặc mảng được hỗ trợ:

- NumPy: tên định dạng là "numpy", để biết thêm thông tin xem [Sử dụng Datasets với NumPy](use_with_numpy)
- PyTorch: tên định dạng là "torch", để biết thêm thông tin xem [Sử dụng Datasets với PyTorch](use_with_pytorch)
- TensorFlow: tên định dạng là "tensorflow", để biết thêm thông tin xem [Sử dụng Datasets với TensorFlow](use_with_tensorflow)
- JAX: tên định dạng là "jax", để biết thêm thông tin xem [Sử dụng Datasets với JAX](use_with_jax)

> [!TIP]
> Xem hướng dẫn [Sử dụng Datasets với TensorFlow](use_with_tensorflow#using-totfdataset) để biết thêm chi tiết về cách tạo hiệu quả một dataset TensorFlow.

Khi một tập dữ liệu được định dạng ở dạng tensor hoặc mảng, tất cả dữ liệu đều được định dạng dưới dạng tensor hoặc mảng (ngoại trừ các kiểu không được hỗ trợ, chẳng hạn như chuỗi trong trường hợp của PyTorch):

```python
>>> ds = Dataset.from_dict({"text": ["foo", "bar"], "tokens": [[0, 1, 2], [3, 4, 5]]})
>>> ds = ds.with_format("torch")
>>> ds[0]
{'text': 'foo', 'tokens': tensor([0, 1, 2])}
>>> ds[:2]
{'text': ['foo', 'bar'],
 'tokens': tensor([[0, 1, 2],
         [3, 4, 5]])}
```

### Định dạng bảng

Bạn có thể sử dụng định dạng dataframes hoặc tables để tối ưu hóa việc tải và xử lý dữ liệu, vì chúng thường cung cấp các thao tác và biến đổi zero-copy được viết bằng các ngôn ngữ cấp thấp.

Dưới đây là danh sách các định dạng dataframe hoặc bảng được hỗ trợ:

- Pandas: tên định dạng là "pandas", để biết thêm thông tin xem [Sử dụng Datasets với Pandas](use_with_pandas)
- Polars: tên định dạng là "polars", để biết thêm thông tin xem [Sử dụng Datasets với Polars](use_with_polars)
- PyArrow: tên định dạng là "arrow", để biết thêm thông tin xem [Sử dụng Datasets với PyArrow](use_with_tensorflow)

Khi một tập dữ liệu được định dạng dưới dạng dataframe hoặc bảng, mỗi hàng hoặc các lô hàng trong tập dữ liệu sẽ được định dạng dưới dạng dataframe hoặc bảng, và các cột của tập dữ liệu sẽ được định dạng dưới dạng series hoặc mảng:

```python
>>> ds = Dataset.from_dict({"text": ["foo", "bar"], "label": [0, 1]})
>>> ds = ds.with_format("pandas")
>>> ds[:2]
  text  label
0  foo      0
1  bar      1
```

Các định dạng này cho phép lặp lại trên dữ liệu nhanh hơn bằng cách tránh sao chép dữ liệu, đồng thời cho phép xử lý dữ liệu nhanh hơn trong [map()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.map) hoặc [filter()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.filter):

```python
>>> ds = ds.map(lambda df: df.assign(upper_text=df.text.str.upper()), batched=True)
>>> ds[:2]
  text  label upper_text
0  foo      0        FOO
1  bar      1        BAR
```

### Biến đổi định dạng tùy chỉnh

Hàm [with_transform()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.with_transform) áp dụng một phép biến đổi định dạng tùy chỉnh theo thời gian thực. Hàm này thay thế bất kỳ định dạng nào đã được chỉ định trước đó. Ví dụ, bạn có thể sử dụng hàm này để thực hiện token hóa và đệm (padding) các token theo thời gian thực. Token hóa chỉ được áp dụng khi các ví dụ được truy cập:

```py
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
>>> def encode(batch):
...     return tokenizer(batch["sentence1"], batch["sentence2"], padding="longest", truncation=True, max_length=512, return_tensors="pt")
>>> dataset = dataset.with_transform(encode)
>>> dataset.format
{'type': 'custom', 'format_kwargs': {'transform': <function __main__.encode(batch)>}, 'columns': ['idx', 'label', 'sentence1', 'sentence2'], 'output_all_columns': False}
```

Ngoài ra còn có [set_transform()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.set_transform) thực hiện cùng chức năng nhưng chạy tại chỗ.

Bạn cũng có thể sử dụng hàm [with_transform()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.with_transform) để giải mã tùy chỉnh trên [Features](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Features).

Ví dụ bên dưới sử dụng gói [`pydub`](http://pydub.com/) như một phương án thay thế cho việc giải mã bằng `torchcodec`:

```py
>>> import numpy as np
>>> from pydub import AudioSegment

>>> audio_dataset_amr = Dataset.from_dict({"audio": ["audio_samples/audio.amr"]})

>>> def decode_audio_with_pydub(batch, sampling_rate=16_000):
...     def pydub_decode_file(audio_path):
...         sound = AudioSegment.from_file(audio_path)
...         if sound.frame_rate != sampling_rate:
...             sound = sound.set_frame_rate(sampling_rate)
...         channel_sounds = sound.split_to_mono()
...         samples = [s.get_array_of_samples() for s in channel_sounds]
...         fp_arr = np.array(samples).T.astype(np.float32)
...         fp_arr /= np.iinfo(samples[0].typecode).max
...         return fp_arr
...
...     batch["audio"] = [pydub_decode_file(audio_path) for audio_path in batch["audio"]]
...     return batch

>>> audio_dataset_amr.set_transform(decode_audio_with_pydub)
```

## Lưu

Khi bộ dữ liệu của bạn đã sẵn sàng, bạn có thể lưu nó dưới dạng Hugging Face Dataset ở định dạng Parquet và sử dụng lại sau này với [load_dataset()](/docs/datasets/v5.2.0/vi/package_reference/loading_methods#datasets.load_dataset).

Lưu bộ dữ liệu của bạn bằng cách cung cấp tên kho dữ liệu trên Hugging Face mà bạn muốn lưu vào cho [push_to_hub()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.push_to_hub):

```python
encoded_dataset.push_to_hub("username/my_dataset")
```

Bạn có thể sử dụng nhiều tiến trình để tải lên song song. Điều này đặc biệt hữu ích nếu bạn muốn tăng tốc quá trình:

```python
dataset.push_to_hub("username/my_dataset", num_proc=8)
```

Sử dụng hàm [load_dataset()](/docs/datasets/v5.2.0/vi/package_reference/loading_methods#datasets.load_dataset) để tải lại bộ dữ liệu (chế độ streaming hoặc không):

```python
from datasets import load_dataset
reloaded_dataset = load_dataset("username/my_dataset", streaming=True)
```

Ngoài ra, bạn có thể lưu cục bộ trên đĩa ở định dạng Arrow. So với Parquet, Arrow không nén nên tốc độ nạp lại nhanh hơn nhiều, rất phù hợp cho việc sử dụng cục bộ trên đĩa và bộ nhớ đệm tạm thời. Tuy nhiên, do kích thước lớn hơn và ít metadata hơn, việc tải lên/tải xuống/truy vấn Arrow chậm hơn Parquet và kém phù hợp hơn cho lưu trữ dài hạn.

Sử dụng hàm [save_to_disk()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.save_to_disk) và [load_from_disk()](/docs/datasets/v5.2.0/vi/package_reference/loading_methods#datasets.load_from_disk) để tải lại bộ dữ liệu từ ổ đĩa của bạn:

```py
>>> encoded_dataset.save_to_disk("path/of/my/dataset/directory")
>>> # later
>>> from datasets import load_from_disk
>>> reloaded_dataset = load_from_disk("path/of/my/dataset/directory")
```

## Xuất

🤗 Datasets hỗ trợ xuất dữ liệu để bạn có thể làm việc với bộ dữ liệu của mình trong các ứng dụng khác. Bảng dưới đây liệt kê các định dạng tệp hiện được hỗ trợ để xuất:

| Loại tệp               | Phương thức xuất                                                       |
| ----------------------- | ------------------------------------------------------------------- |
| CSV                     | [Dataset.to_csv()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.to_csv)                                                  |
| JSON                    | [Dataset.to_json()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.to_json)                                                 |
| Parquet                 | [Dataset.to_parquet()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.to_parquet)                                              |
| SQL                     | [Dataset.to_sql()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.to_sql)                                                  |
| Đối tượng Python trong bộ nhớ | [Dataset.to_pandas()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.to_pandas), `Dataset.to_polars()` or [Dataset.to_dict()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.to_dict) |

Ví dụ, xuất bộ dữ liệu của bạn ra tệp CSV như sau:

```py
>>> encoded_dataset.to_csv("path/of/my/dataset.csv")
```

Sử dụng đường dẫn `hf://` để xuất ra [kho Dataset](https://huggingface.co/docs/hub/datasets-overview) hoặc [Storage Bucket](https://huggingface.co/docs/hub/storage-buckets) trên Hugging Face:

```py
>>> encoded_dataset.to_csv("hf://datasets/username/dataset_name/path/of/my/dataset.csv")
>>> encoded_dataset.to_csv("hf://buckets/username/raw_data_bucket/path/of/my/dataset.csv")
```

