社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python生成器表达式:如何从循环中添加和条件?

1Z10 • 5 年前 • 1575 次点击  

具有下列距离矩阵 dist :

dist = [[[ 0, 0],
[ 5,  0],
[ 1,  0],
[ 1,  1],
[11,  3],
[ 3,  6],
[ 5,  5]],

[[ 5,  0],
[ 0,  0],
[ 6,  0],
[ 4,  1],
[ 6,  3],
[ 2,  6],
[10,  5]],

[[ 1,  0],
[ 6,  0],
[ 0,  0],
[ 2,  1],
[12,  3],
[ 4,  6],
[ 4,  5]],

[[ 1,  1],
[ 4,  1],
[ 2,  1],
[ 0,  0],
[10,  2],
[ 2,  7],
[ 6,  6]],

[[11,  3],
[ 6,  3],
[12,  3],
[10,  2],
[ 0,  0],
[ 8,  9],
[16,  8]],

[[ 3,  6],
[ 2,  6],
[ 4,  6],
[ 2,  7],
[ 8,  9],
[ 0,  0],
[ 8,  1]],

[[ 5,  5],
[10,  5],
[ 4,  5],
[ 6,  6],
[16,  8],
[ 8,  1],
[ 0,  0]]]

我需要建立一个 generator expression 具有 AND 这种情况:

gexp = (dist[:, :, 0] <= 1) & (dist[:, :, 1] <= 2)

意思是我想要一个 True 当两个条件都成立时(对于列0和列1),如下所示(我将其打印为列表理解语法):

[array([[ True, False,  True,  True, False, False, False],
       [False,  True, False, False, False, False, False],
       [ True, False,  True, False, False, False, False],
       [ True, False, False,  True, False, False, False],
       [False, False, False, False,  True, False, False],
       [False, False, False, False, False,  True, False],
       [False, False, False, False, False, False,  True]])]

我有一个列列表:

columns = ['weight', 'height']

它们的阈值:

thresholds = {'weight': 1.0, 'height': 1.0}

以及相应的指标:

indexes = {'weight': 0, 'height': 1}

我试图以这种方式构建生成器表达式:

    dynamic_gexpr = [dist[:,:,indexes.get(column)] <= thresholds.get(column) for column in columns]

但我不知道如何在一列和另一列之间添加AND条件。上面的表达式似乎更像或条件一样处理它,给出以下输出:

[array([[ True, False,  True,  True, False, False, False],
       [False,  True, False, False, False, False, False],
       [ True, False,  True, False, False, False, False],
       [ True, False, False,  True, False, False, False],
       [False, False, False, False,  True, False, False],
       [False, False, False, False, False,  True, False],
       [False, False, False, False, False, False,  True]]), array([[ True,  True,  True,  True, False, False, False],
       [ True,  True,  True,  True, False, False, False],
       [ True,  True,  True,  True, False, False, False],
       [ True,  True,  True,  True, False, False, False],
       [False, False, False, False,  True, False, False],
       [False, False, False, False, False,  True,  True],
       [False, False, False, False, False,  True,  True]])]
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/49611
 
1575 次点击  
文章 [ 3 ]  |  最新文章 5 年前
Serge Ballesta
Reply   •   1 楼
Serge Ballesta    6 年前

正如@1Z10在评论中所建议的, np.reduce 最终会成为你的朋友。

您应该首先构建一个布尔矩阵,其中每个最高级别的行是子数组与其相应阈值的比较。那就用 np.还原 nb.logical_and 在这个矩阵上得到你的结果,不管需要多少比较:

dynamic_expr = np.logical_and.reduce(np.array(
    [dist[:, :, indexes[col]] <= thresholds[col]
     for col in columns]))
print(dynamic_expr)

输出为:

[[ True False  True  True False False False]
 [False  True False False False False False]
 [ True False  True False False False False]
 [ True False False  True False False False]
 [False False False False  True False False]
 [False False False False False  True False]
 [False False False False False False  True]]
ilamaaa
Reply   •   2 楼
ilamaaa    6 年前

我用列表理解来应用构建生成器的条件,用另一种方法来做,感觉不对。不管怎样,不确定这是不是你想要的。

x = ([second[0] <= 1 and second[1] <=2 for second in first] for first in dist)
for y in x:
    print(y)

输出:

[True, False, True, True, False, False, False]
[False, True, False, False, False, False, False]
[True, False, True, False, False, False, False]
[True, False, False, True, False, False, False]
[False, False, False, False, True, False, False]
[False, False, False, False, False, True, False]
[False, False, False, False, False, False, True]

对于你想要的版本,感觉不对

x = ((second[0] <= 1 and second[1] <=2 for second in first) for first in dist)

for y in x:
    print([next(y),next(y),next(y),next(y),next(y),next(y),next(y)])

输出相同

现在编写一个单独的函数来进行比较

def compare(a,b):
    return all([a[i] <= b[i] for i in range(len(a))])

x = ((compare(second, [1,2]) for second in first) for first in dist)

for y in x:
    print([next(y),next(y),next(y),next(y),next(y),next(y),next(y)])
Jeppe
Reply   •   3 楼
Jeppe    6 年前

如果您添加更多的列,这应该会扩展。 arrays 将为每个条件保存一个数组。每一个都是通过 reduce 从而累积 bitwise_and 所有阵列中。

import numpy as np
from functools import reduce
columns = ['weight', 'height']
thresholds = {'weight': 1.0, 'height': 1.0}
indexes = {'weight': 0, 'height': 1}

l = np.array(dist)
arrays = [(l[:, :, indexes[column]] <= thresholds[column]) for column in columns]
l2 = reduce(lambda a, acc : np.bitwise_and(a, acc), arrays)
print(l2)

输出:

[[ True False  True  True False False False]
 [False  True False False False False False]
 [ True False  True False False False False]
 [ True False False  True False False False]
 [False False False False  True False False]
 [False False False False False  True False]
 [False False False False False False  True]]