当重复少于 n 次时,从 numpy 数组中删除行

Posted

技术标签:

【中文标题】当重复少于 n 次时,从 numpy 数组中删除行【英文标题】:Remove rows from numpy array when its repeated less than n times 【发布时间】:2016-09-12 09:43:40 【问题描述】:

从 numpy 数组中删除重复少于 n 次的行

原因:

我有一个大小为 1 GB 的数据集。 它有 29.118.021 个样本和 108.390 个类。

但是,有些课程只有 1 个样本。或者 3 个样本,等等……

问题: 我想从 numpy 数组中删除出现/重复少于 N 次的行/类。

参考 XgBoost : The least populated class in y has only 1 members, which is too few

尝试失败

train_x, train_y, test_x, test_id = loader.load()

n_samples = train_y.shape[0]
unique_labels, y_inversed = np.unique(train_y, return_inverse=True)
label_counts = bincount(y_inversed)
min_labels = np.min(label_counts)

print "Total Rows ", n_samples
print "unique_labels ", unique_labels.shape[0]
print "label_counts ", label_counts[:]
print "min labels ", min_labels

unique_labels = unique_labels.astype(np.uint8)
unique_amounts = np.empty(shape=unique_labels.shape, dtype=np.uint8)
for u in xrange(0, unique_labels.shape[0]):
    if u % 100 == 0:
        print "Processed ", str(u)
    for index in xrange(0, train_y.shape[0]):
        if train_y[index] == unique_labels[u]:
            unique_amounts[u] = unique_amounts[u] + 1

for k in xrange(0, unique_amounts.shape[0]):
    if unique_amounts[k] == 1:
        print "\n"
        print "value :", unique_amounts[k]
        print "at ", k

上面的代码太长了。即使我让它在服务器上运行了一整晚,它甚至没有达到一半的处理。


加载方法

这是我的加载方法。 我可以加载它并将其保存为数据框。

def load():
    train = pd.read_csv('input/train.csv', index_col=False, header='infer')
    test = pd.read_csv('input/test.csv', index_col=False, header='infer')

    # drop useless columns
    train.drop('row_id', axis=1, inplace=True)

    acc = train["accuracy"].iloc[:].as_matrix()
    x = train["x"].iloc[:].as_matrix()
    y = train["y"].iloc[:].as_matrix()
    time = train["time"].iloc[:].as_matrix()
    train_y = train["place_id"].iloc[:].as_matrix()

    ####################################################################################
    acc = acc.reshape(-1, 1)
    x = x.reshape(-1, 1)
    y = y.reshape(-1, 1)
    time = time.reshape(-1, 1)
    train_y = train_y.reshape(-1, 1)

    ####################################################################################

    train_x = np.hstack((acc, x, y, time))

    ####################################################################################

    acc = test["accuracy"].iloc[:].as_matrix()
    x = test["x"].iloc[:].as_matrix()
    y = test["y"].iloc[:].as_matrix()
    time = test["time"].iloc[:].as_matrix()
    test_id = test['row_id'].iloc[:].as_matrix()

    #######################
    acc = acc.reshape(-1, 1)
    x = x.reshape(-1, 1)
    y = y.reshape(-1, 1)
    time = time.reshape(-1, 1)
    #######################

    test_x = np.hstack((acc, x, y, time))

    return train_x, train_y, test_x, test_id

【问题讨论】:

类或标签仅对数据框有意义,对 numpy 数组没有意义 我可以将它作为数据框加载 【参考方案1】:

numpy_indexed 包(免责声明:我是它的作者)包含一个多重函数,它导致执行此类操作的可读性非常强:

import numpy_indexed as npi
samples_mask = npi.multiplicity(train_y) >= n_min
filtered_train_y = train_y[samples_mask]

【讨论】:

感谢您的回复,它一定会帮助其他人解决同样的问题! 我将使用这个 numpy-indexed 实现。谢谢! 有一个问题。如果我从 train_y 数组中删除行 'r',我还必须从 train_x 中删除行 'r',有什么想法吗? filtered_train_x = train_x[samples_mask]【参考方案2】:

我会将您的数据保存为数据框格式。 这样,您可以使用pandas 模块中的一些有用方法,而且应该比循环更快。

首先,通过df['labels'].value_counts() 获取与df 关联的不同标签。 (我假设标签列名称是'labels')。

然后,只获取数据框中少于n_min 行的标签。

vc = df['labels'].value_counts()
labels = vc[vc < n_min].index
df.drop(labels, inplace=True)

希望有帮助!

【讨论】:

感谢您的回复,它一定会帮助其他人解决同样的问题!

以上是关于当重复少于 n 次时,从 numpy 数组中删除行的主要内容,如果未能解决你的问题,请参考以下文章

如何从数组的numpy数组中删除外部数组[重复]

从numpy数组中删除换行符[重复]

从 pandas 转换为 numpy 后,如果数组包含 nan,则删除“nan”或减少 numpy 数组的长度 [重复]

删除 NumPy 数组中具有重复项的行

Numpy - 使用另一个数组的行从一个数组中删除行

numpy数组列表中N个最高元素的索引[重复]