使用Lambda表达式操作NumPy数组:训练标签填充及to_categorical报错问题
嘿,我懂你遇到的问题了——想用生成式快速生成重复的标签数组,结果传给keras.utils.to_categorical时报错,这是因为你写的生成式返回的结构和NumPy、Keras期望的不一样。
为什么你的代码不行?
你写的np.array([k]*size for k, size in enumerate(train_sizes)),其实是把每个[k]*size作为独立的元素传入NumPy,最终得到的是一个object类型的数组(里面每个元素是一个小数组),类似这样:
array([array([0, 0, 0]), array([1, 1, 1])], dtype=object)
而to_categorical需要的是一维整数数组(或者形状为(n_samples, 1)的二维数组),这种嵌套的object数组它没法处理,所以触发了TypeError。
正确的实现方式
这里有两种简单高效的方法可以得到你想要的结果:
方法1:用嵌套列表推导式展开成扁平列表
先把所有标签元素展开成一个扁平的列表,再转成NumPy数组,最后按需reshape成列向量:
# 假设train_sizes是类似[3, 3]的列表 train_labels = np.array([k for k, size in enumerate(train_sizes) for _ in range(size)]) # 转成你要的列向量形式 train_labels = train_labels.reshape(-1, 1)
这样得到的就是标准的二维整数数组,完全符合to_categorical的要求。
方法2:用NumPy的repeat函数(更简洁高效)
NumPy自带的np.repeat可以直接实现“重复指定次数”的需求,代码更简洁,性能也更好:
train_labels = np.repeat(np.arange(len(train_sizes)), train_sizes).reshape(-1, 1)
np.arange(len(train_sizes))生成标签索引(比如0,1),np.repeat会把每个索引对应重复train_sizes里的次数,最后reshape成列向量就搞定了。
验证效果
当train_sizes = [3,3]时,两种方法都会得到:
array([[0], [0], [0], [1], [1], [1]])
这时再传给keras.utils.to_categorical(train_labels, num_classes=class_size)就不会报错啦。
内容的提问来源于stack exchange,提问作者Rocking chief

