在python中,根据条件从三个不同值范围的列表中选择最佳索引

在python中,根据条件从三个不同值范围的列表中选择最佳索引,python,Python,我有一个有三个键的dict,它由一个相同长度的列表组成。例如,键“a”有一个长度为5的列表,由0到6000的值组成。类似地,长度为5的键“b”的值范围为0到1.0。最后,具有相同长度的键“c”的值范围为(1x1)到(2000x2000) 我必须选择一个介于0和4之间的索引,条件是“a”的值不能小于200。“b”的值不能低于0.95。然后,在满足这两个条件的指标中选择“c”的最高值 虚拟数据如下所示: index a b c 0

我有一个有三个键的dict,它由一个相同长度的列表组成。例如,键“a”有一个长度为5的列表,由0到6000的值组成。类似地,长度为5的键“b”的值范围为0到1.0。最后,具有相同长度的键“c”的值范围为(1x1)到(2000x2000)

我必须选择一个介于0和4之间的索引,条件是“a”的值不能小于200。“b”的值不能低于0.95。然后,在满足这两个条件的指标中选择“c”的最高值

虚拟数据如下所示:

  index     a          b           c
    0      600       0.99      (100x105)
    1      150        1.0       (50x40)
    2      820       0.75      (500x480)
    3      500       0.96      (200x190)
    4      400       0.97      (120x110)
这里,根据这两个条件,我可以将索引过滤到0、3和4。在这三个指数中,“c”的最大值是指数3。所以答案是
3500 0.96(200x190)

如何以最有效的方式选择此选项?我想我可能需要用熊猫。我怎样才能用熊猫来做呢?还有,如何以最具蟒蛇风格的方式来做呢

我对编码比较陌生。我很难弄明白

编辑: 这段话的一段代码

{
'a' : [600, 150, 820, 500, 400]
'b' : [0.99, 1.0, 0.75, 0.96, 0.97]
'c' : [(100,105), (50,40), (500,480), (200,190), (120,110)]
}

对于
numpy
,这一点相对简单,尽管列
c
的格式有点奇怪,但它提供了一个有趣的转折点

import numpy as np

d = {
'a' : [600, 150, 820, 500, 400],
'b' : [0.99, 1.0, 0.75, 0.96, 0.97],
'c' : [(100,105), (50,40), (500,480), (200,190), (120,110)]
}

# Load as numpy arrays. 
d_np = {key: np.array(value) for key, value in d.items()}

# Create logical mask based on given requirements
mask = np.logical_and(d_np['a'] > 200, d_np['b'] > 0.95)

# Multiply 'c' along dimension 1
c_product = np.prod(d_np['c'], axis=1)

# Get index of maximum value. Note that this index is relative to masked array.
max_index_masked = np.argmax(c_product[mask])

# Get original 'c' value. Need to mask the array so that our indexing works.
max_value = d_np['c'][mask][max_index_masked]

# Get index relative to unmasked array
index = np.arange(d_np['c'].shape[0])[mask][max_index_masked]
print(index)

对于
numpy
,这一点相对简单,尽管列
c
的格式有点奇怪,但它提供了一个有趣的转折点

import numpy as np

d = {
'a' : [600, 150, 820, 500, 400],
'b' : [0.99, 1.0, 0.75, 0.96, 0.97],
'c' : [(100,105), (50,40), (500,480), (200,190), (120,110)]
}

# Load as numpy arrays. 
d_np = {key: np.array(value) for key, value in d.items()}

# Create logical mask based on given requirements
mask = np.logical_and(d_np['a'] > 200, d_np['b'] > 0.95)

# Multiply 'c' along dimension 1
c_product = np.prod(d_np['c'], axis=1)

# Get index of maximum value. Note that this index is relative to masked array.
max_index_masked = np.argmax(c_product[mask])

# Get original 'c' value. Need to mask the array so that our indexing works.
max_value = d_np['c'][mask][max_index_masked]

# Get index relative to unmasked array
index = np.arange(d_np['c'].shape[0])[mask][max_index_masked]
print(index)

一个没有numpy的简单解决方案,使用列表切片

    data = {
        'a' : [600, 150, 820, 500, 400],
        'b' : [0.99, 1.0, 0.75, 0.96, 0.97],
        'c' : [(100,105), (50,40), (500,480), (200,190), (120,110)]
    }
    select_a = [index_a for index_a in range(len(data['a'])) if data['a'][index_a] >=200]
    select_b = [index_b for index_b in select_a if data['b'][index_b]>=0.95]
    result = select_b[0]
    for index_c in select_b:
        if((data['c'][index_c][0]*data['c'][index_c][1])>(data['c'][result][0]*data['c'][result][1])):
            result = index_c
    print(result)

一个没有numpy的简单解决方案,使用列表切片

    data = {
        'a' : [600, 150, 820, 500, 400],
        'b' : [0.99, 1.0, 0.75, 0.96, 0.97],
        'c' : [(100,105), (50,40), (500,480), (200,190), (120,110)]
    }
    select_a = [index_a for index_a in range(len(data['a'])) if data['a'][index_a] >=200]
    select_b = [index_b for index_b in select_a if data['b'][index_b]>=0.95]
    result = select_b[0]
    for index_c in select_b:
        if((data['c'][index_c][0]*data['c'][index_c][1])>(data['c'][result][0]*data['c'][result][1])):
            result = index_c
    print(result)
输出为3


输出为3。

以下是您拥有的数据:

d = {'a':[600,150,820,500,400], 'b':[0.99,1.0,0.75,0.96,0.97], 'c':[(100,105),(50,40),(500,480),(200,190),(120,110)]}
a_thresh = 200
b_thresh = 0.95
这是解决问题的一种方法,只需对字典中的列表进行一次检查:

from operator import mul

list_len = len(d['a'])
found_i = 0
for i in range(list_len):
    if ((d['a'][i]>=a_thresh) and (d['b'][i]>=b_thresh) and 
        (mul(*d['c'][i]) > mul(*d['c'][found_i]))):
        found_i = i
print (found_i)
输出:

3

当然,您可以在不导入和使用
mul()
函数的情况下执行此操作。这只会使循环条件看起来有点紧凑。
mul()
仅用于将元组的两部分相乘。要在不使用
mul()
的情况下执行此操作,请搜索
(mul(*d['c'][3])并将其替换为较长的表达式
((d['c'][3][0]*d['c'][3][1])(d['c'][found i][0]*d['c'][found i][1])
以下是您拥有的数据:

d = {'a':[600,150,820,500,400], 'b':[0.99,1.0,0.75,0.96,0.97], 'c':[(100,105),(50,40),(500,480),(200,190),(120,110)]}
a_thresh = 200
b_thresh = 0.95
这是解决问题的一种方法,只需对字典中的列表进行一次检查:

from operator import mul

list_len = len(d['a'])
found_i = 0
for i in range(list_len):
    if ((d['a'][i]>=a_thresh) and (d['b'][i]>=b_thresh) and 
        (mul(*d['c'][i]) > mul(*d['c'][found_i]))):
        found_i = i
print (found_i)
输出:

3

当然,您可以在不导入和使用
mul()
函数的情况下执行此操作。这只会使循环条件看起来有点紧凑。
mul()
仅用于将元组的两部分相乘。要在不使用
mul()
的情况下执行此操作,请搜索
(mul(*d['c'][3])并将其替换为较长的表达式
((d['c'][3][0]*d['c'][3][1])(d['c'][found i][0]*d['c'][found i][1])
。尽量使它可读

import numpy as np

d = {
    'a': [600, 150, 820, 500, 400],
    'b': [0.99, 1.0, 0.75, 0.96, 0.97],
    'c': [(100, 105), (50, 40), (500, 480), (200, 190), (120, 110)]
}

a = np.array([
    np.arange(len(d['a'])),
    d['a'],
    d['b'],
    np.prod(np.array(d['c']), axis=1)
])

a = a[:, a[1] >= 200]
a = a[:, a[2] >= .95]
a = a[:, np.argmax(a[3])]
index = int(a[0])

print('result:', d['a'][index], d['b'][index], d['c'][index])

我试图找到一个简单的解决方案。尽量使它可读

import numpy as np

d = {
    'a': [600, 150, 820, 500, 400],
    'b': [0.99, 1.0, 0.75, 0.96, 0.97],
    'c': [(100, 105), (50, 40), (500, 480), (200, 190), (120, 110)]
}

a = np.array([
    np.arange(len(d['a'])),
    d['a'],
    d['b'],
    np.prod(np.array(d['c']), axis=1)
])

a = a[:, a[1] >= 200]
a = a[:, a[2] >= .95]
a = a[:, np.argmax(a[3])]
index = int(a[0])

print('result:', d['a'][index], d['b'][index], d['c'][index])


你能给你的口述写一段代码吗?“我想我可能需要用熊猫”。没有熊猫也能做到。但是你仍然只想用熊猫来做这件事吗?我已经用代码片段编辑了这篇文章。我不想用熊猫。事实上,我试着用filter和numpy来实现它。尚未成功。您的元组看起来像
(100105)、(50,40)
。对吗?或者应该是
(100100)、(50,50)
,等等?(在每个元组中,两个元素是否相等?)。没有熊猫也能做到。但是你仍然只想用熊猫来做这件事吗?我已经用代码片段编辑了这篇文章。我不想用熊猫。事实上,我试着用filter和numpy来实现它。尚未成功。您的元组看起来像
(100105)、(50,40)
。对吗?或者应该是
(100100)、(50,50)
,等等?(在每个元组中,两个元素是否相等?)。但答案应该是指数3,而不是指数3的值。然而,你的回答为我指明了正确的方向。如果我在代码中添加另一行:
np.where(d_np['c']==max_value)[0]
我得到了
数组([3,3])
,这正是我所需要的。谢谢。对不起,我错过了。我已经用另一种方法修改了答案以获得索引。@AndrewGuy:喜欢你创建
d\u np
的简洁!谢谢你的回答。但答案应该是指数3,而不是指数3的值。然而,你的回答为我指明了正确的方向。如果我在代码中添加另一行:
np.where(d_np['c']==max_value)[0]
我得到了
数组([3,3])
,这正是我所需要的。谢谢。对不起,我错过了。我已经用另一种方法修改了答案以获得索引。@AndrewGuy:喜欢你创建
d\u np
的简洁!此解决方案在列表长度上进行两次传递。第一次通过时,使用列表的
for
循环获取
max
值。第二次遍历列表用于查找出现
max
值的
索引。如果您想要一个只遍历一次的解决方案,可以查看我的答案。此解决方案在列表长度上遍历两次。第一次通过时,使用列表的
for
循环获取
max
值。列表的第二步是查找
索引
,在该索引处出现
max
值。如果你想要一个只通过一次的解决方案,你可以看看我的答案。在使用单行程序之前,我已经用这种方法解决了这个问题。好吧,我只是想知道为什么你称单行程序为“最有效”的方法,当它不是的时候?我不是说它没有效率。我只是说,如果它通过两次,它不可能是“最有效的”。顺便说一句,一份清单