在NumPy中按类划分训练数据

在NumPy中按类划分训练数据,numpy,scipy,scikit-learn,data-cleaning,Numpy,Scipy,Scikit Learn,Data Cleaning,我有一个50000 x 784数据矩阵(50000个样本和784个特征)和相应的50000 x 1类向量(类是整数0-9)。我正在寻找一种有效的方法,将数据矩阵分组为10个数据矩阵和类向量,每个数据矩阵和类向量只包含特定类0-9的数据 我似乎找不到一个优雅的方法来实现这一点,除了通过循环数据矩阵并以这种方式构造其他10个矩阵之外 有人知道有没有一种干净的方法来处理scipy、numpy或sklearn中的内容吗?如果您的数据和标签矩阵采用numpy格式,您可以执行以下操作: data_class

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

我似乎找不到一个优雅的方法来实现这一点,除了通过循环数据矩阵并以这种方式构造其他10个矩阵之外


有人知道有没有一种干净的方法来处理
scipy
numpy
sklearn
中的内容吗?

如果您的
数据和
标签
矩阵采用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)])

在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\u splitted
将是一个数组列表,在
classes
中找到的每个类对应一个数组。使用
SAMPLES=10
FEATURES=2
CLASSES=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]])]

如果要确保排序是稳定的,即排序后同一类中的数据点保持相同的相对顺序,则需要在@Jaime numpy最优答案之后指定
sorter=np.argsort(classes,kind='mergesort')
,我建议您专门从事数据操作:

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数组,因此效率得以保持。

我没有得到
数据[labels==3,:]
中的
,:
,索引不是太多了吗?使用
数据[labels==3]
还不够吗?是的,在2D情况下就足够了。当你有更多的维度时,它会变得复杂,我习惯于显式。如果你不想指定范围,你可以使用:
np.array([data[labels==I]for I in np.unique(labels)])
最佳解决方案取决于数据大小(所有矩阵都适合内存?),数据形状(是数据numpy数组,字符串。感谢这些精确的观点。出于好奇,为什么需要排序而不是直接索引?对于这个只有10个类的特殊情况,您的解决方案可能是一个更好的选择。但是如果你有很多类,你必须为每个类迭代整个数组一次。很快,带有排序的O(nlogn)方法将击败带有索引的O(mn)方法。