datasets库一些基本方法:filter、map、select等


使用 datasets库,对数据集进行处理可以更方便与高效;

常用的csv、excel 和 json 等数据格式,可以很方便的转换为datasets的样式;

官方文档:🤗 Datasets is a library for easily accessing and sharing datasets for Audio, Computer Vision, and Natural Language Processing (NLP) tasks. https://huggingface.co/docs/datasets/v2.21.0/en/process#select-and-filter

在这里插入图片描述
左侧有很多文章列表,右侧是Process文章的目录,该目录有很多的不错的内容。
有很多内容本博客没有提及,推荐读者阅读原始文档。

安装

pip install datasets

导入 huggingface 数据集

from datasets import load_dataset

ds = load_dataset("fancyzhx/ag_news")

由于huggingface的服务器在海外,一般都连接不上。如果连接不上,使用代理进行连接。先运行下述代理设置,再运行上述的数据集导入:

import os
os.environ['HTTP_PROXY'] = 'http://127.0.0.1:7890'
os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:7890'

ds的features:

ds["train"].features

输出结果:

{'text': Value(dtype='string', id=None),
 'label': ClassLabel(names=['World', 'Sports', 'Business', 'Sci/Tech'], id=None)}

fancyzhx/ag_news 是一个文本分类数据集,有['World', 'Sports', 'Business', 'Sci/Tech'] 四个类别。

ds

输出结果:

DatasetDict({
    train: Dataset({
        features: ['text', 'label'],
        num_rows: 120000
    })
    test: Dataset({
        features: ['text', 'label'],
        num_rows: 7600
    })
})
ds["test"][0]

输出结果:

{'text': "Fears for T N pension after talks Unions representing workers at Turner   Newall say they are 'disappointed' after talks with stricken parent firm Federal Mogul.",
 'label': 2}

导入本地数据集

from datasets import load_dataset, Dataset

导入json文件为数据集:

query_dataset = load_dataset(
    "json", 
    data_files="xxx.json", 
    split="train"
)

导出为json:

dataset.to_json(
        "xxx.jsonl",
        force_ascii=False,
    )

从字典/列表导入为数据集:

corpus = Dataset.from_dict({"text": corpus_list})

filter

datasets的数据集对象有filter方法,实现对数据集元素进行筛选。
比如,想筛选出在训练集中,label 全为2的数据。

tmp = ds["train"].filter(lambda x: x["label"] == 2)
print(tmp)
print(tmp[0])

输出结果:

Filter: 100%|██████████| 120000/120000 [00:00<00:00, 453257.78 examples/s]
Dataset({
    features: ['text', 'label'],
    num_rows: 30000
})
{'text': "Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\band of ultra-cynics, are seeing green again.", 'label': 2}

如上述的输出结果所示,在训练集中label为2的数据有30000条。最后一行是筛选出的一个示例。

map

数据集转换,原始的数据集通常可能不满足需求,要对其进行一些转化。
要让大模型对文本进行分类,需要给样例数据中添加一些提示词。

下述是大模型给文本分类的提示词:

prompt_cls = """你是文本分类领域的专家,请你给下述文本分类,把它分到下述类别中:
* World
* Sports
* Business
* Science / Technology'

text是待分类的文本,label是文本的类别:
text: {text}
label: 
"""

想把原始的数据集中的text,自动放入到{text}中,实现代码如下:

def trans2llm(item):
    item["text"] = prompt_cls.format(text=item["text"])
    return item

tmp = ds["test"].map(trans2llm)
print(tmp[0])

输出结果:

Map: 100%|██████████| 7600/7600 [00:00<00:00, 57726.64 examples/s]
{'text': "你是文本分类领域的专家,请你给下述文本分类,把它分到下述类别中:\n* World\n* Sports\n* Business\n* Science / Technology'\n\ntext是待分类的文本,label是文本的类别:\ntext: Fears for T N pension after talks Unions representing workers at Turner   Newall say they are 'disappointed' after talks with stricken parent firm Federal Mogul.\nlabel: \n", 'label': 2}

如上述结果所示,使用map完成了数据集的转换。
map需要传入一个数据处理的函数,本例子中的函数是:trans2llm
trans2llm接收的参数是原始数据集的item,返回的结果是一个新的item。

select

数据集采样,随机采样、下标采样等;
有时候,可能只想要数据集的随机一部分样本、某些下标的样本。

filter 函数筛选
select 筛选下标

ds["train"].select([0, 10, 20, 30, 40, 50])

输出结果:

Dataset({
    features: ['text', 'label'],
    num_rows: 6
})

如果我们要在数据集中,随机采样,只需要传入随机的下标就可以:

import random  
numbers = list(range(1000))
# 从这个列表中随机选择100个不重复的数  
random_numbers = random.sample(numbers, 100)
# 打印生成的随机数列表  
print(random_numbers)
# 通过长度验证是否有重复元素
print(len(set(random_numbers)) == len(random_numbers))

获取随机采样的样本数据:

ds["train"].select(random_numbers)

输出结果:

Dataset({
    features: ['text', 'label'],
    num_rows: 100
})

数据集拼接

使用拼接函数,把一些数据集拼接到一起。
若想区分训练集和测试集,使用train_test_split 切分开。

from datasets import concatenate_datasets
dataset = concatenate_datasets([true_dataset, false_dataset])
# dataset.train_test_split(train_size=0.8)

add_column

添加属性列:

dataset["train"] = dataset["train"].add_column("index", list(range(786701)))

rename_column

属性列重命名:

dataset["train"] = dataset["train"].rename_column("idx", "file_sent_index")
<think>好的,我现在需要帮用户解决EEException: Image.select: Band pattern ‘B2’ was applied to an Image with no bands这个错误。用户之前问过类似的语法错误问题,现在可能是他们在使用Google Earth Engine时遇到了这个问题。首先,我得理解这个错误的具体原因。根据错误信息,用户在使用Image.select方法时,指定的波段名称'B2'在目标图像中不存在,导致选择失败,因为图像没有波段。 接下来,我需要回忆一下Google Earth Engine中常见的情况。可能的原因包括:图像加载不正确,导致没有波段;波段的名称拼写错误;图像集合过滤条件过严,导致返回了空图像;或者处理过程中意外移除了所有波段。 我应该分步骤解释这些可能的原因,并给出相应的解决方法。例如,检查图像是否加载正确,确认波段名称是否正确,检查过滤条件是否正确,以及使用print语句调试图像信息。此外,用户可能需要检查图像处理步骤中是否有移除波段的操作,比如误用了某些函数。 用户可能对GEE的调试方法不太熟悉,所以需要详细说明如何使用print(image.bandNames())来查看波段名称,或者使用size()检查集合是否为空。同时,应该提醒用户注意不同卫星数据集的不同波段命名习惯,比如Landsat和Sentinel的差异。 另外,用户可能没有意识到在处理图像集合时,如果过滤后得到一个空集合,接下来的操作就会出错。这时候需要检查日期范围、几何范围等过滤条件是否正确。还有,如果在代码中进行了映射操作,可能在函数内部错误地移除了所有波段,导致后续无法选择波段。 我应该提供具体的示例代码,展示错误和修正后的正确写法,比如加载Landsat图像时正确选择波段,或者处理集合时确保非空。同时,强调使用调试工具的重要性,比如打印图像信息,使用getInfo()获取元数据,以及参考官方文档中的调试指南链接。 最后,确保回答结构清晰,分点列出原因和解决方法,让用户能够逐步排查问题。可能还需要提醒用户检查数据集的可用性,或者是否有权限访问相应的数据集,不过这种情况比较少见。总之,重点在于帮助用户系统地检查他们的代码,找出导致图像无波段的原因,并提供解决方案。</think>### 地球引擎异常解析:`EEException: Image.select: Band pattern ‘B2’ was applied to an Image with no bands` 这个错误是 **Google Earth Engine (GEE)** 在尝试通过波段名称(如 `'B2'`)选择波段时抛出的,表示**目标影像中不存在匹配的波段**或**影像本身为空**。以下是详细分析和解决方法: --- #### 1. **错误原因** - **影像加载错误**:未正确加载包含目标波段的影像(如数据集名称拼写错误或访问权限问题)。 - **波段名称不匹配**:指定的波段名称(如 `'B2'`)与影像实际波段名称不一致(例如大小写敏感、卫星数据集差异)。 - **空影像**:对影像集合(`ImageCollection`)的过滤或操作返回了无波段的空影像(如时间/空间范围过滤过严)。 - **处理链错误**:在数据处理的中间步骤中意外移除了所有波段(例如误用 `image.clip()` 后未保留波段)。 --- #### 2. **排查步骤** ##### 步骤 1:验证影像是否包含波段 ```javascript // 打印影像的波段名称(示例) print('影像波段:', image.bandNames()); // 若返回空列表,则影像无波段 ``` ##### 步骤 2:检查数据集名称和加载方式 - **确认数据集标识符正确**(如 `LANDSAT/LC08/C02/T1_L2` 或 `COPERNICUS/S2`)。 - **检查影像的筛选条件**(如时间范围、云量过滤)是否导致结果为空: ```javascript var collection = ee.ImageCollection('XXX') .filterDate('2020-01-01', '2020-01-31') .filterBounds(geometry); print('集合大小:', collection.size()); // 若为0,说明无影像 ``` ##### 步骤 3:核对波段名称 - **不同卫星的波段命名可能不同**(例如 Sentinel-2 的 `'B2'` 对应 Landsat 的 `'SR_B2'`)。 - 检查数据集文档(如 [Landsat 8 波段表](https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LC08_C02_T1_L2#bands))。 ##### 步骤 4:检查数据处理链 - 确认是否在 `map()` 操作中移除了波段(例如误用 `image.expression()` 或 `image.clip()` 后未保留原始波段)。 --- #### 3. **解决方案** ##### 方案 1:修正波段名称 ```javascript // 错误示例:Landsat 8 的蓝光波段应为 'SR_B2',而非 'B2' var image = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_044034_20200101'); var corrected = image.select('SR_B2'); // 正确波段名称 ``` ##### 方案 2:避免空影像 - 放宽影像集合的过滤条件: ```javascript var collection = ee.ImageCollection('COPERNICUS/S2') .filterDate('2020-01-01', '2020-02-28') // 扩展时间范围 .filterBounds(geometry) .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)); ``` ##### 方案 3:修复数据处理链 - 确保操作中保留原始波段: ```javascript var processedImage = originalImage .clip(geometry) .copyProperties(originalImage, ['system:bands']); // 保留波段信息 ``` --- #### 4. **调试技巧** - **打印元数据**:使用 `print(image)` 或 `image.getInfo()` 查看影像结构。 - **可视化验证**:通过 `Map.addLayer(image, {}, 'Preview')` 检查影像是否有效。 - **参考文档**:通过错误提示中的 [调试指南链接](https://developers.google.com/earth-engine/guides/debugging#no-bands) 定位问题。 --- #### 示例修正 **错误代码**: ```javascript var image = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_044034_20200101'); var band = image.select('B2'); // Landsat 8 的波段名称是 'SR_B2' ``` **修正后**: ```javascript var image = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_044034_20200101'); var band = image.select('SR_B2'); // 使用正确的波段名称 ``` --- 若问题仍未解决,建议提供完整的代码片段和数据集名称,以便进一步诊断!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jieshenai

为了遇见更好的文章

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值