Цикл по массиву на основе первого индекса - PullRequest
0 голосов
/ 29 мая 2019

У меня есть два массива, и я хочу перебрать второй массив, чтобы возвращать только массивы, первый элемент которых равен элементу из другого массива.

 a = [10, 11, 12, 13, 14]
 b = [[9, 23, 45, 67, 56, 23, 54], [10, 8, 52, 30, 15, 47, 109], [11, 81, 
 152, 54, 112, 78, 167], [13, 82, 84, 63, 24, 26, 78], [18, 182, 25, 63, 96, 
 104, 74]]

У меня есть два разных массива, a и b. Я хотел бы найти способ просмотреть каждый из подмассивов (?) В b, в котором первое значение равно значениям в массиве a для создания нового массива, c.

Результат, который я ищу:

  c = [[10, 8, 52, 30, 15, 47, 109],[11, 81, 152, 54, 112, 78, 167],[13, 82, 84, 63, 24, 26, 78]]

Есть ли в Python инструмент, позволяющий сделать это так, как в Excel есть MATCH ()?

Я пытался зацикливаться таким образом:

 for i in a:
      if i in b:
          print (b)

Но поскольку в массиве есть другие элементы, этот способ не работает. Любая помощь будет принята с благодарностью.

Дальнейшее объяснение проблемы:

a = [5, 6, 7, 9, 12]

Я читаю в файле Excel, используя XLRD (b_csv_data):

 Start  Count   Error   Constant    Result1 Result2 Result3 Result4
 5       41       0       45             23      54      66       19
 5.4     44       1       21             52      35       6       50
 6       16       1       42             95      39       1       13
 6.9     50       1       22             71      86      59       97
 7       38       1       43             50      47      83       67
  8      26       1       29             100     63      15       40
 9       46       0       28             85       9      27       81
 12      43       0       21             74      78      20       85

Затем я создал вид для чтения в выбранном количестве строк. Для простоты этот файл выше имеет всего несколько строк. Мой текущий файл имеет около 100 строк.

for r in range (1, 7): #skipping headers and only wanting first few rows to start

     b_raw = b_csv_data.row_values(r) 
     b = np.array(b_raw) # I created this b numpy array from the line of code above

Ответы [ 3 ]

2 голосов
/ 29 мая 2019

Использование np.isin -

In [8]: b[np.isin(b[:,0],a)]
Out[8]: 
array([[ 10,   8,  52,  30,  15],
       [ 11,  81, 152,  54, 112],
       [ 13,  82,  84,  63,  24]])

С отсортированным a мы также можем использовать np.searchsorted -

idx = np.searchsorted(a,b[:,0])
idx[idx==len(a)] = 0
out = b[a[idx] == b[:,0]]

Если у вас есть массив с различным количеством элементов в строке, который по сути является массивом списков, вам нужно изменить часть среза. Так что, в этом случае, получите первые элементы off -

b0 = [bi[0] for bi in b]

Затем используйте b0 для замены всех экземпляров b[:,0] в ранее опубликованных методах.

1 голос
/ 29 мая 2019

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

c = [l for l in b if l[0] in a]

Вывод:

[[10, 8, 52, 30, 15], [11, 81, 152, 54, 112], [13, 82, 84, 63, 24]]

Если ваши list или array значительно большие, использование numpy.isin может быть значительно быстрее:

b[np.isin(b[:, 0], a), :]

Контрольный показатель:

a = [10, 11, 12, 13, 14]
b = [[9, 23, 45, 67, 56], [10, 8, 52, 30, 15], [11, 81, 152, 54, 112], 
 [13, 82, 84, 63, 24], [18, 182, 25, 63, 96]]

list_comp, np_isin = [], []
for i in range(1,100):
    a_test = a * i
    b_test = b * i
    list_comp.append(timeit.timeit('[l for l in b_test if l[0] in a_test]', number=10, globals=globals()))
    a_arr = np.array(a_test)
    b_arr = np.array(b_test)
    np_isin.append(timeit.timeit('b_arr[np.isin(b_arr[:, 0], a_arr), :]', number=10, globals=globals()))

enter image description here

Хотя это не ясно и кратко, я бы рекомендовал использовать listпонимание, если b короче 100. В противном случае, numpy ваш путь.

0 голосов
/ 29 мая 2019

Вы делаете это наоборот.Лучше пройтись по элементам массива b и проверить, присутствует ли он в a.Если да, то выведите этот элемент b.См. Ответ ниже.

a = [10, 11, 12, 13, 14]
b = [[9, 23, 45, 67, 56, 23, 54], [10, 8, 52, 30, 15, 47, 109], [11, 81, 152, 54, 112, 78, 167], [13, 82, 84, 63, 24, 26, 78], [18, 182, 25, 63, 96, 104, 74]]

for bb in b:  # if you want to check only the first element of b is in a
    if bb[0] in a:
            print(bb)

for bb in b:   # if you want to check if any element of b is in a
    for bbb in bb:
        if bbb in a:
            print(bb)

Вывод:

[10, 8, 52, 30, 15, 47, 109]
[11, 81, 152, 54, 112, 78, 167]
[13, 82, 84, 63, 24, 26, 78]
...