我有一个2D numpy数组,大约有12列和1000多行,每个单元格包含1到5的数字。我正在根据我的点系统搜索列的最佳六列,其中1和2生成-1点和4和5给出+1。
如果某个六元组中的某行包含例如[1,4,5,3,4,3],则该行的点应为+2,因为3 * 1 + 1 *( - 1)= 2.下一行可能是[1,2,3,3,3,3],应该是-3分。
首先,我尝试了一个strait前向循环解决方案,但我意识到有665 280个可能的列组合要进行比较,当我还需要搜索最好的五元组,四元组等时,循环将永远占用。
是否有一种更聪明的方式来解决我的问题?
答案 0 :(得分:1)
import numpy as np
import itertools
N_rows = 10
arr = np.random.random_integers(5, size=(N_rows,12))
x = np.array([0,-1,-1,0,1,1])
y = x[arr]
print(y)
score, best_sextuple = max((y[:,cols].sum(), cols)
for cols in itertools.combinations(range(12),6))
print('''\
score: {s}
sextuple: {c}
'''.format(s = score, c = best_sextuple))
产生,例如,
score: 6
sextuple: (0, 1, 5, 8, 10, 11)
<强>解释强>:
首先,让我们生成一个随机的例子,包含12列和10行:
N_rows = 10
arr = np.random.random_integers(5, size=(N_rows,12))
现在我们可以使用numpy索引将arr
1,2,...,5中的数字转换为值-1,0,1(根据您的评分系统):
x = np.array([0,-1,-1,0,1,1])
y = x[arr]
接下来,让我们使用itertools.combinations
生成6列的所有可能组合:
for cols in itertools.combinations(range(12),6)
和
y[:,cols].sum()
然后给出cols
的分数,选择列(六个)。
最后,使用max
来挑选得分最高的六人组:
score, best_sextuple = max((y[:,cols].sum(), cols)
for cols in itertools.combinations(range(12),6))
答案 1 :(得分:1)
import numpy
A = numpy.random.randint(1, 6, size=(1000, 12))
points = -1*(A == 1) + -1*(A == 2) + 1*(A == 4) + 1*(A == 5)
columnsums = numpy.sum(points, 0)
def best6(row):
return numpy.argsort(row)[-6:]
bestcolumns = best6(columnsums)
allbestcolumns = map(best6, points)
bestcolumns
现在将按升序包含最佳的6列。按照类似的逻辑,allbestcolumns
将包含每行中最好的六列。
答案 2 :(得分:0)
扩展unutbu上面的更长答案,可以自动生成蒙版的分数数组。由于每次通过循环时您的值得分都是一致的,因此每个值的得分只需要计算一次。在应用分数之前和之后,在示例6x10阵列上执行此操作的方式略显不雅。
>>> import numpy
>>> values = numpy.random.randint(6, size=(6,10))
>>> values
array([[4, 5, 1, 2, 1, 4, 0, 1, 0, 4],
[2, 5, 2, 2, 3, 1, 3, 5, 3, 1],
[3, 3, 5, 4, 2, 1, 4, 0, 0, 1],
[2, 4, 0, 0, 4, 1, 4, 0, 1, 0],
[0, 4, 1, 2, 0, 3, 3, 5, 0, 1],
[2, 3, 3, 4, 0, 1, 1, 1, 3, 2]])
>>> b = values.copy()
>>> b[ b<3 ] = -1
>>> b[ b==3 ] = 0
>>> b[ b>3 ] = 1
>>> b
array([[ 1, 1, -1, -1, -1, 1, -1, -1, -1, 1],
[-1, 1, -1, -1, 0, -1, 0, 1, 0, -1],
[ 0, 0, 1, 1, -1, -1, 1, -1, -1, -1],
[-1, 1, -1, -1, 1, -1, 1, -1, -1, -1],
[-1, 1, -1, -1, -1, 0, 0, 1, -1, -1],
[-1, 0, 0, 1, -1, -1, -1, -1, 0, -1]])
顺便提一下,this线程声称直接在numpy中创建组合将比itertools的性能提高约5倍,但可能会牺牲一些可读性。