可以将datasets中的Dataset实例看做是一张数据表。map方法会将输入的function
按照指定的方式应用在每一行(每一行称为一个example)上。本文采用一下示例进行说明:
from datasets import Dataset # datasets.__version__ = '2.13.0'
x = [{"text": "good", "label": 1}, {"text": "bad", "label": 0}, {"text": "great", "label": 2}]
ds = Dataset.from_list(x)
function
是map方法的核心,其介绍单独放在下列章节。其它常用参数的说明如下:
function位置参数接受一个可调用对象,本质是该可调用对象对数据表中的每行进行处理。按照布尔型位置参数with_indices, with_rank, batched
的取值, function有8种签名。其中batched表示可调用对象一次处理一行还是多行,with_indices表示是否将样本的索引编号传入可调用对象, with_rank表示是否将进程rank传入可调用对象。
当设置batched=False
时,可调用对象依次处理每一行。在默认情况下,可调用对象的签名为function(example: Dict[str, Any]) -> Dict[str, Any]
,example中的键为数据表中的所有列。可使用input_columns
指定哪些列进入example中。可调用对象应该返回一个Dict对象,并使用返回结果更新数据表。
from typing import Dict, Any
def func(exam: Dict[str, Any]) -> Dict[str, Any]:
return {"text_length": len(exam["text"])}
print(ds.map(func).data)
如果指定with_indices=True
,则可调用对象中应该指定一个位置参数用于接受样本索引编号。
def func_with_indices(exam, index):
return {"text_length": len(exam["text"]), "row_index": int(index)}
print(ds.map(func_with_indices, with_indices=True, batched=False).data)
如果指定with_rank=True
,则可调用对象中应指定一个位置参数用于接受进程rank。并且应当设置num_proc
大于1,否则进程rank的值是相同的。
def func_with_rank(exam, rank):
return {"text_length": len(exam["text"]), "proc_rank": int(rank)}
print(ds.map(func_with_rank, with_rank=True, batched=False, num_proc=2).data)
如果同时指定with_indices=True
与with_rank=True
,则可调用对象中接受样本索引编号的位置参数应置于接受进程rank位置参数之前。如def function(example, idx, rank): ...
。
def func_with_index_rank(exam, index, rank):
return {"text_length": len(exam["text"]), "row_index": int(index), "proc_rank": int(rank)}
print(ds.map(func_with_rank, with_indices=True, with_rank=True, batched=False, num_proc=2).data)
当设置batched=True
时,可调用对象会对样本进行批处理,批的大小可以通过batch_size
控制,默认一个批为1000条样本。此情况下签名应满足function(batch: Dict[str, List]) -> Dict[str, List]
。batch中的键仍然是数据表中的列名称,值为多行数据组成的列表。
def batched_func(batch):
return {"text_length": [len(text) for text in batch["text]]}
print(ds.map(batched_func, batched=True, batch_size=2).data)
x = [{'text': 'good', 'label': torch.tensor(1, dtype=torch.long)},
{'text': 'bad', 'label': torch.tensor(0, dtype=torch.long)},
{'text': 'great', 'label': torch.tensor(2, dtype=torch.long)}]
ds = Dataset.from_list(x)
print(type(x[0]["label"])) # torch.Tensor
print(ds.map().data)
def to_tensor(exam):
return {"label" : torch.tensor(exam["label"], dtype=torch.long)}
print(ds.map(to_tensor).data) # 结果一致,数据表中的label均为整数型