如何从CSV加载含多维特征Tensor的TensorFlow数据集?
解决CSV多维特征列转Tensor及维度可变数组问题
一、将f3列转为2×3 Tensor的实现方法
要处理分号分隔的f3列,核心是先按字符串读取,再通过映射函数完成拆分、转数值和形状重塑,具体步骤如下:
- 加载原始数据时指定f3列为字符串类型
默认情况下tf.data.experimental.make_csv_dataset会自动推断列类型,但f3是分号分隔的字符串,需要手动指定column_defaults确保按字符串读取:
import tensorflow as tf # 假设CSV列顺序为f1, f2, f3,根据实际情况调整列默认类型 column_defaults = [tf.float32, tf.float32, tf.string] dataset = tf.data.experimental.make_csv_dataset( "your_dataset.csv", batch_size=32, column_defaults=column_defaults, num_epochs=1, shuffle=False )
- 编写映射函数处理f3列
通过字符串拆分、数值转换和形状重塑,将f3列转为2×3的Tensor。注意要确保每个样本的f3列拆分后恰好有6个数值(对应2×3的元素数):
def process_f3(feature_batch): # 按分号拆分字符串 split_f3 = tf.strings.split(feature_batch['f3'], sep=';') # 转换为浮点型数值 numeric_f3 = tf.strings.to_number(split_f3, out_type=tf.float32) # 重塑为2×3的Tensor feature_batch['f3'] = tf.reshape(numeric_f3, (-1, 2, 3)) return feature_batch # 对数据集应用映射处理 dataset = dataset.map(process_f3)
- 可选:处理无效样本
如果存在f3列数值数量不符合要求的样本,可添加过滤逻辑避免报错:
def process_f3_safe(feature_batch): split_f3 = tf.strings.split(feature_batch['f3'], sep=';') # 筛选出拆分后长度为6的样本 valid_mask = tf.equal(tf.shape(split_f3)[1], 6) # 过滤所有特征列的无效样本 feature_batch = {key: tf.boolean_mask(val, valid_mask) for key, val in feature_batch.items()} split_f3 = tf.boolean_mask(split_f3, valid_mask) numeric_f3 = tf.strings.to_number(split_f3, out_type=tf.float32) feature_batch['f3'] = tf.reshape(numeric_f3, (-1, 2, 3)) return feature_batch dataset = dataset.map(process_f3_safe)
二、关于维度可变数组的支持情况
TensorFlow的tf.data数据集支持维度可变的数组,但需要用**RaggedTensor(不规则张量)**来存储,具体处理方式如下:
- 将可变长度列转为RaggedTensor
如果f3列的数值数量不固定,拆分后直接转为RaggedTensor即可:
def process_variable_f3(feature_batch): split_f3 = tf.strings.split(feature_batch['f3'], sep=';') numeric_f3 = tf.strings.to_number(split_f3, out_type=tf.float32) # 转为RaggedTensor存储可变长度数据 feature_batch['f3'] = tf.RaggedTensor.from_tensor(numeric_f3) return feature_batch dataset = dataset.map(process_variable_f3)
- 模型中处理RaggedTensor
如果后续要将RaggedTensor输入到Keras模型,需要在输入层指定ragged=True:
input_f3 = tf.keras.layers.Input(shape=(None,), dtype=tf.float32, ragged=True) # 后续可通过RaggedTensor的相关操作处理,比如转成固定长度(填充)或直接用支持RaggedTensor的层
也可以将RaggedTensor填充到统一长度,转为普通Tensor使用:
def pad_ragged_to_fixed(feature_batch): # 获取当前batch中f3列的最大长度 max_len = tf.reduce_max(feature_batch['f3'].row_lengths()) # 填充到最大长度 feature_batch['f3'] = feature_batch['f3'].to_tensor(default_value=0., shape=(-1, max_len)) return feature_batch dataset = dataset.map(pad_ragged_to_fixed)
内容的提问来源于stack exchange,提问作者Sergey Shcherbakov
相关产品推荐
相关产品推荐

