You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Hugging Face Dataset中指定单一特征为numpy数组?

问题

使用load_dataset()加载Mozilla Common Voice(v11)数据集时,得到的数据集ds里audio.array是numpy数组,但不知道怎么复现这个效果。请问如何仅将单个特征设置为ndarray类型?

查看Common Voice数据集的示例:

>>> tt = load_dataset(
    data_args.dataset_name,
    data_args.dataset_config_name,
    split=f'{data_args.train_split_name}[:15%]',  # 只加载前15%数据
    cache_dir=model_args.cache_dir,
    token=model_args.token,
)
>>> type(tt.select([0])['audio'][0]['path'])
<class 'str'>
>>> type(tt.select([0])['audio'][0]['array'])
<class 'numpy.ndarray'>
>>> type(tt.select([0])['path'][0]) # 数据集里重复存了路径作为顶级特征
<class 'str'>

但在自定义代码里没法单独存储numpy数组,只发现用ds = ds.with_format('np')时,重新加载的数据集所有顶级特征都会变成numpy类型(测试结果如下):

>>> type(test_ds['path'][0])
<class 'numpy.str_'>

需求是仅把“audio -> array”设为一维numpy数组。以下是创建并重新加载数据集以检查类型的测试代码:

#!/usr/bin/env python
# 尝试在huggingface dataset中保存和重新加载numpy数组
# 加载后的数组类型必须是numpy array()
from datasets import Dataset, Features, Array2D, Sequence, Value
import numpy as np

audio_arrays = [np.random.rand(16000), np.random.rand(16000)] 

features = Features({
  # 每个audio包含音频数据的np数组和源音频文件路径
  'audio': Sequence({
    #'array': Sequence(feature=Array2D(shape=(None,), dtype="float32")),
    'array': Sequence(feature=Value('float32')),
    'path': Value('string'),
  }),
  'path': Value('string'), # Common Voice数据集里也重复存了路径
})

ddata = {
    'path': [],        # 字符串列表
    'audio': [],       # 字典列表
}

ddata['path'] = ['/foo0/', '/bar0/'] # 确保能看到存储差异
ddata['audio'] = [
        {'array': audio_arrays[0], 'path': '/foo1/' },
        {'array': audio_arrays[1], 'path': '/bar1/', },
]
ds = Dataset.from_dict(ddata)
ds = ds.with_format('np')
ds.save_to_disk('/tmp/ds.ds') 

loaded_dataset = Dataset.load_from_disk('/tmp/ds.ds')
ld = loaded_dataset
au = ld['audio'][0]
ar = ld['audio'][0]['array']
print("Type of audio array:", type(ar))
print("Type of path:", type(ld['path'][0]))
print("Type of au path:", type(ld['audio'][0]['path']))
import ipdb; ipdb.set_trace(context=16); pass
解决方案

要实现仅让audio.array保持numpy数组类型,其他特征保留原生Python类型,不需要全局设置with_format('np'),正确做法是在定义Features时用Array类型而非Sequence指定音频数组,并且无需全局格式化整个数据集。

步骤1:修正Features定义

使用Array类型(而非Sequence(Value('float32')))定义audio.array,数据集会自动将其识别为numpy数组,同时其他特征保持原生类型:

from datasets import Dataset, Features, Array, Value

features = Features({
    'audio': {
        'array': Array(dtype='float32', shape=(None,)),  # 一维可变长度float32数组
        'path': Value('string'),
    },
    'path': Value('string'),
})

shape=(None,)表示数组长度可变,适配音频数据的特性。

步骤2:创建并保存数据集

无需调用with_format('np'),直接创建数据集并保存:

audio_arrays = [np.random.rand(16000), np.random.rand(16000)] 

ddata = {
    'path': ['/foo0/', '/bar0/'],
    'audio': [
        {'array': audio_arrays[0], 'path': '/foo1/' },
        {'array': audio_arrays[1], 'path': '/bar1/', },
    ]
}

ds = Dataset.from_dict(ddata, features=features)
ds.save_to_disk('/tmp/ds.ds') 

步骤3:加载并验证类型

重新加载后,audio.array会是numpy数组,而path等特征保持原生Python字符串类型:

loaded_dataset = Dataset.load_from_disk('/tmp/ds.ds')

print("Type of audio array:", type(loaded_dataset['audio'][0]['array']))  # <class 'numpy.ndarray'>
print("Type of top-level path:", type(loaded_dataset['path'][0]))  # <class 'str'>
print("Type of audio path:", type(loaded_dataset['audio'][0]['path']))  # <class 'str'>

原理说明

Common Voice数据集能自动让audio.array成为numpy数组,核心是它的特征定义使用了Array类型描述音频数组,而非通用的Sequence。全局with_format('np')会强制所有特征转为numpy类型,而精准定义特征类型,可以实现仅指定单个字段为numpy数组,其他字段保持原生类型。

内容的提问来源于stack exchange,提问作者Jaggz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:33:14