替代python中的'for循环'将快速运行

时间:2018-01-09 16:53:03

标签: python arrays numpy

在我的python脚本中,我有一个2d numpy数组(名为original_data) 1)我必须找到所有唯一的行 2)创建一个空数组 3)将original_data中的所有行与此unique_rows进行比较,当它与任何unique_rows行匹配时,将该特定行的唯一值的rowindex附加到创建的新数组

original_data = np.array([[1, 2, 7, 1, 2, 1],
   [1, 2, 7, 1, 2, 1],
   [1, 2, 7, 1, 2, 1],
   [1, 2, 6, 1, 2, 1],
   [1, 3, 5, 1, 1, 1],
   [1, 2, 5, 1, 1, 1],
   [1, 2, 5, 1, 1, 1],
   [1, 2, 5, 1, 1, 1],
   [1, 2, 5, 1, 1, 1],
   [1, 2, 5, 1, 1, 1]])
y = np.ascontiguousarray(original_data).view(np.dtype((np.void, original_data.dtype.itemsize * original_data.shape[1])))
_, idx = np.unique(y, return_index=True)
unique_rows = original_data[idx]
att = []
for i in range(original_data.shape[0]):
  for j in range(unique_rows.shape[0]):
    if(np.array_equal(original_data[i],unique_rows[j])):
        att.append(j)
        break
    else:
        continue 

这运行良好,但如果我考虑大数据集,那么这个for循环不是一个好选择,因为它需要花费很多时间来运行。任何人都可以建议我替换这两个跑得快得多的forloops。

2 个答案:

答案 0 :(得分:1)

unique的另一个选项就是这样做:

y = np.ascontiguousarray(original_data).view(np.dtype((np.void, original_data.dtype.itemsize * original_data.shape[1])))
_, att = np.unique(y, return_inverse=True)

从numpy版本1.13开始,void dtype的技巧已成为unique的一部分,因此您可以使用新的axis关键字参数:

_, att = np.unique(original_data, return_inverse=True, axis=0)

如果您需要更快,您可以计算行的哈希值并对其进行处理。但是,那么处理哈希冲突可能很难用numpy来实现..

答案 1 :(得分:0)

任何此类循环的步骤1是尝试使其成为列表理解:

att = [j
   for i in range(original_data.shape[0])
   for j in range(unique_rows.shape[0])
   if np.array_equal(original_data[i], unique_rows[j])]

在那之后,重新思考你想要完​​成什么,以及如何做到这一点。在这种情况下,如果您使用了以下词典理解,那么您将获得您正在寻找的内容(假设您不需要按照您在其中找到的相同顺序排序唯一行原始数据):

data = [tuple(row) for row in original_data]
unique_rows = set(data)
unique_row_map = {row: i for i, row in enumerate(unique_rows)}
att = [unique_row_map[row] for row in data]