Сравнение y-координаты в списке кортежей с условием - PullRequest
2 голосов
/ 05 октября 2019

У меня есть список:

 a = [(1, 2), (3, 4), (4, 5), (6, 7), (5,90)]
 # Stores list of x,y coordinates

и список:

 b = [(1, 2), (10, 1), (3, 10), (4, 9), (10,9)]

и переменная z = 90

Теперь я хочу заменить в a, где она имеет координату y в a> = of, b с координатой y + 2, с условием, что координата y никогда не должна превышать некоторого значения z. Таким образом, y +2 никогда не должен превышать z.

Поскольку здесь a имеет эквивалент или больше b в:

[(1,2), (3,4), (5,90)]

Я хочу заменить на a такой, что это становится:

a = [(1,4), (3,6), (4,5), (6,7), (5,90)]

Как я могу это сделать?

Я знаю, что существует метод с numpy такой, что:

np.where(a >= b) , do something;

, но не уверенкак я мог использовать это в этом случае.

Ответы [ 5 ]

1 голос
/ 05 октября 2019

Кортежи в Python являются неизменяемыми и не могут быть изменены. Вы должны создать новый список новых кортежей, скажем, со списком:

a = [(ax, min(z, ay + 2 if ay >= by else ay))
        for ((ax, ay), (_, by)) in zip(a, b)]

Numpy бесполезен в вашем случае, потому что он не работает с кортежами.

1 голос
/ 05 октября 2019

Вы должны иметь списки вместо кортежей

a = [[1, 2], [3, 4], [4, 5], [6, 7], [5,90]]
b = [[1, 2], [10, 1], [3, 1], [4, 9], [10,9]]
z = 90
for n,na in enumerate(a):
    if na[1] >= b[n][1]:
        if na[1] < 89:
            a[n][1] += 2
print(a)

Кортежи

Это код, если вам нужно иметь вывод в кортеже

a = [(1, 2), (3, 4), (4, 5), (6, 7), (5,90)]
b = [(1, 2), (10, 1), (3, 10), (4, 9), (10,9)]

a1 = [list(x) for x in a]
b1 = [list(x) for x in b]
z = 90
for n,na in enumerate(a1):
    if na[1] >= b1[n][1]:
        if na[1] < 89:
            a1[n][1] += 2
        elif na[1] == 89:
            a1[n][1] = 90

a = [tuple(x) for x in a1]

print(a)

[(1, 4), (3, 6), (4, 5), (6, 7), (5, 90)]

Если вы хотите, чтобы numpy это делал

import numpy as np
a = [(1, 2), (3, 4), (4, 5), (6, 7), (5,90)]
b = [(1, 2), (10, 1), (3, 10), (4, 9), (10,9)]
a, b = np.array(a), np.array(b)

z = 90

second_element = np.s_[:, 1]
is_bigger = a[second_element] >= b[second_element]
a[second_element][is_bigger] = np.clip(a[second_element][is_bigger] + 2,
                    a_min=None, a_max=z)
a = [tuple(x) for x in a]
print(a)

выход

[(1, 4), (3, 6), (4, 5), (6, 7), (5, 90)]

0 голосов
/ 05 октября 2019

Вы можете сделать это с numpy по

a = [[1, 2], [3, 4], [4, 5], [6, 7], [5,90]]
b = [[1, 2], [10, 1], [3, 1], [4, 9], [10,9]]
a = np.array(a)
b = np.array(b)

mask_ab = a[:, 1] >= b[:, 1]
mask_smaller = a[:, 1] < 89
mask = np.logical_and(mask_ab, mask_smaller)
a[mask, 1] += 2
0 голосов
/ 05 октября 2019

Вы должны использовать списки как массивы, чтобы использовать NumPy. Это упорядочит xs и ys как столбцы. Это облегчает использование срезов (np.s_) для формирования масок в соответствии с условиями. Затем вы можете использовать np.clip, чтобы ограничить данные, чтобы они оставались в определенном диапазоне. Таким образом, вы можете использовать векторизованные операции для быстрых манипуляций, если ваши данные большие.

>>> a = np.array([(1, 2), (3, 4), (4, 5), (6, 7), (5,90)])
>>> b = np.array([(1, 2), (10, 1), (3, 10), (4, 9), (10,9)])
>>> z = 90

>>> ys = np.s_[:, 1]
>>> mask = a[ys] >= b[ys]
>>> a[ys][mask] = np.clip(a[ys][mask] + 2, a_min=None, a_max=z)
>>> a
array([[ 1,  4],
       [ 3,  6],
       [ 4,  5],
       [ 6,  7],
       [ 5, 90]])
0 голосов
/ 05 октября 2019

Попробуйте это:

a = [(1, 2), (3, 4), (4, 5), (6, 7), (5,90)]
b = [(1, 2), (10, 1), (3, 10), (4, 9), (10, 9)]
z=90
c=[]
for index, val in enumerate(a):
    try:
        y = (val[1]+2 if index < len(b) and len(b[index])>1 and val[1]>=b[index][1] and val[1]+2 <= z else val[1])
        c.append((val[0],y))
    except:
        print("Provide proper inputs.")
a = c

print(a)

Или используя понимание списка:

c = [(a[index][0],(a[index][1]+2 if a[index][1] >= b[index][1] and a[index][1]+2 < z else a[index][1])) for index in range(len(a))]
a=c
print(c)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...