NumPy中按类分区训练数据

时间:2016-03-06 02:16:39

标签: numpy scipy scikit-learn data-cleaning

我有一个50000 x 784数据矩阵(50000个样本和784个特征)和相应的50000 x 1类向量(类是整数0-9)。我正在寻找一种有效的方法将数据矩阵分组为10个数据矩阵和类向量,每个数据矩阵只包含特定0-9类的数据。

除了循环数据矩阵并构建其他10个矩阵之外,我似乎无法找到一种优雅的方法。

是否有人知道在scipynumpysklearn中是否有一种干净的方法可以执行此操作?

3 个答案:

答案 0 :(得分:2)

如果您的datalabels矩阵采用numpy格式,您可以这样做:

data_class_3 = data[labels == 3, :]

如果他们不是,请将它们变成numpy格式:

import numpy as np
data = np.array(data)
labels = np.array(labels)
data_class_3 = data[labels == 3, :]

如果您愿意,可以自动循环并对所有标签执行此操作。像这样:

import numpy as np
split_classes = np.array([data[labels == i, :] for i in range(10)])

答案 1 :(得分:2)

可能最简洁的方法是在numpy中这样做,特别是如果你有很多课程,通过排序:

SAMPLES = 50000
FEATURES = 784
CLASSES = 10
data = np.random.rand(SAMPLES, FEATURES)
classes = np.random.randint(CLASSES, size=SAMPLES)

sorter = np.argsort(classes)
classes_sorted = classes[sorter]
splitter, = np.where(classes_sorted[:-1] != classes_sorted[1:])
data_splitted = np.split(data[sorter], splitter + 1)

data_splitted将是一个数组列表,每个类在classes中找到一个。使用SAMPLES = 10FEATURES = 2CLASSES = 3运行上述代码,我得到:

>>> data
array([[ 0.45813694,  0.47942962],
       [ 0.96587082,  0.73260743],
       [ 0.70539842,  0.76376921],
       [ 0.01031978,  0.93660231],
       [ 0.45434223,  0.03778273],
       [ 0.01985781,  0.04272293],
       [ 0.93026735,  0.40216376],
       [ 0.39089845,  0.01891637],
       [ 0.70937483,  0.16077439],
       [ 0.45383099,  0.82074859]])

>>> classes
array([1, 1, 2, 1, 1, 2, 0, 2, 0, 1])

>>> data_splitted 
[array([[ 0.93026735,  0.40216376],
        [ 0.70937483,  0.16077439]]),
 array([[ 0.45813694,  0.47942962],
        [ 0.96587082,  0.73260743],
        [ 0.01031978,  0.93660231],
        [ 0.45434223,  0.03778273],
        [ 0.45383099,  0.82074859]]),
 array([[ 0.70539842,  0.76376921],
        [ 0.01985781,  0.04272293],
        [ 0.39089845,  0.01891637]])]

如果要确保排序稳定,即排序后同一类中的数据点保持相同的相对顺序,则需要指定sorter = np.argsort(classes, kind='mergesort')

答案 2 :(得分:1)

在@Jaime numpy最佳答案之后,我建议你pandas,专门从事数据操作:

import pandas
df=pandas.DataFrame(data,index=classes).sort_index()

然后df.loc[i]是您的班级i

如果你想要一个清单,只需做

 metadata=[df.loc[i].values for i in range(10)]

因此metadata[i]是您想要的子集,或者使用pandas创建一个面板。所有这些都基于numpy数组,因此效率得以保留。