Как сравнить два списка и извлечь положение, индекс и соседей? - PullRequest
1 голос
/ 07 марта 2020

Предположим, у нас есть два списка:

list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9, 10]

Это базовая c структура:

     Columns
Rows    0      1      2      3      4
0       1      2      3      4      5
1       6      7      8      9      10

Каждый из элементов должен напечатать строку с небольшим количеством метаданных ( index, position и соседей):

row/col   Print statement
0/0       "Row index=0, Column Index=0, Value=1, Value below=6, Value to the right = 2"
0/1       "Row index=0, Column Index=1, Value=2, Value below=7, Value to the right = 3"
0/2       "Row index=0, Column Index=2, Value=3, Value below=8, Value to the right = 4"
0/3       "Row index=0, Column Index=3, Value=4, Value below=9, Value to the right = 5"
0/4       "Row index=0, Column Index=4, Value=5, Value below=10, Value to the right = NaN"
1/0       "Row index=1, Column Index=0, Value=6, Value below=NaN, Value to the right = 7"
1/1       "Row index=1, Column Index=1, Value=7, Value below=NaN, Value to the right = 8"
1/2       "Row index=1, Column Index=2, Value=8, Value below=NaN, Value to the right = 9"
1/3       "Row index=1, Column Index=3, Value=9, Value below=NaN, Value to the right = 10"
1/4       "Row index=1, Column Index=4, Value=10, Value below=NaN, Value to the right = NaN"

Есть ли что-то вроде понимания списка или какого-либо другого способа сравнить эти два списка как можно быстрее?

Я бы не хотел использовать для / циклы while, поскольку они считаются очень медленными.

РЕДАКТИРОВАТЬ: решение будет ядром функции больших данных, которая должна обрабатывать миллионы сравнений. Использование традиционных для циклов чрезвычайно замедлило бы мою функцию. Вот почему я ищу более быстрый способ сделать это.

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Если вам нужен список строк, то вам нужно выполнить итерацию - по каждому элементу. Подобное форматирование строк работает со скалярными элементами, а не с целыми массивами.

Можно генерировать значения, используя операции с целым массивом. Но результатом будет некая форма массива, а не список строк.

Например:

In [198]: list1 = [1, 2, 3, 4, 5] 
     ...: list2 = [6, 7, 8, 9, 10]                                                             
In [199]: arr = np.array([list1,list2])                                                        
In [200]: arr                                                                                  
Out[200]: 
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])

Простой способ перебора массива с отображением индексов:

In [201]: list(np.ndenumerate(arr))                                                            
Out[201]: 
[((0, 0), 1),
 ((0, 1), 2),
 ((0, 2), 3),
 ((0, 3), 4),
 ((0, 4), 5),
 ((1, 0), 6),
 ((1, 1), 7),
 ((1, 2), 8),
 ((1, 3), 9),
 ((1, 4), 10)]

Это все еще итерация. Мы можем получить индексы в виде массива с помощью:

In [215]: np.indices(arr.shape)                                                                
Out[215]: 
array([[[0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1]],

       [[0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4]]])
In [216]: I,J = np.indices(arr.shape)

и составить эти индексы со значениями:

In [218]: np.stack((I.ravel(),J.ravel(),arr.ravel()),axis=1)                                   
Out[218]: 
array([[ 0,  0,  1],
       [ 0,  1,  2],
       [ 0,  2,  3],
       [ 0,  3,  4],
       [ 0,  4,  5],
       [ 1,  0,  6],
       [ 1,  1,  7],
       [ 1,  2,  8],
       [ 1,  3,  9],
       [ 1,  4, 10]])

Чтобы получить приведенные ниже и правильные значения, мы можем сгенерировать дополненный массив:

In [223]: arr1 = np.pad(arr.astype(float),[(0,1),(0,1)],mode='constant',constant_values=np.nan)
     ...:                                                                                      
In [224]: arr1                                                                                 
Out[224]: 
array([[ 1.,  2.,  3.,  4.,  5., nan],
       [ 6.,  7.,  8.,  9., 10., nan],
       [nan, nan, nan, nan, nan, nan]])

Обратите внимание, что мне пришлось преобразовать массив в число с плавающей точкой, чтобы принять значение с плавающей точкой np.nan.

И объединить все:

In [225]: np.stack((I.ravel(),J.ravel(),arr.ravel(),arr1[1:,:-1].ravel(),arr1[:-1,1:].ravel()),
     ...: axis=1)                                                                              
Out[225]: 
array([[ 0.,  0.,  1.,  6.,  2.],
       [ 0.,  1.,  2.,  7.,  3.],
       [ 0.,  2.,  3.,  8.,  4.],
       [ 0.,  3.,  4.,  9.,  5.],
       [ 0.,  4.,  5., 10., nan],
       [ 1.,  0.,  6., nan,  7.],
       [ 1.,  1.,  7., nan,  8.],
       [ 1.,  2.,  8., nan,  9.],
       [ 1.,  3.,  9., nan, 10.],
       [ 1.,  4., 10., nan, nan]])

Чтобы получить список строк, мы можем определить формат строки:

In [230]: astr = "Row index={}, Column index={}, Value={}, Value below={}, Value to the right={}"  

и применить его для достижения строки (да, это действительно повторяется)

In [233]: for row in Out[225]: 
     ...:     print(astr.format(*row)) 
     ...:                                                                                      
Row index=0.0, Column index=0.0, Value=1.0, Value below=6.0, Value to the right=2.0
Row index=0.0, Column index=1.0, Value=2.0, Value below=7.0, Value to the right=3.0
Row index=0.0, Column index=2.0, Value=3.0, Value below=8.0, Value to the right=4.0
Row index=0.0, Column index=3.0, Value=4.0, Value below=9.0, Value to the right=5.0
Row index=0.0, Column index=4.0, Value=5.0, Value below=10.0, Value to the right=nan
Row index=1.0, Column index=0.0, Value=6.0, Value below=nan, Value to the right=7.0
Row index=1.0, Column index=1.0, Value=7.0, Value below=nan, Value to the right=8.0
Row index=1.0, Column index=2.0, Value=8.0, Value below=nan, Value to the right=9.0
Row index=1.0, Column index=3.0, Value=9.0, Value below=nan, Value to the right=10.0
Row index=1.0, Column index=4.0, Value=10.0, Value below=nan, Value to the right=nan

Если мы опускаем все эти ravel мы получаем массив значений 3d:

In [234]: np.stack((I,J,arr,arr1[1:,:-1],arr1[:-1,1:]),axis=2)                                 
Out[234]: 
array([[[ 0.,  0.,  1.,  6.,  2.],
        [ 0.,  1.,  2.,  7.,  3.],
        [ 0.,  2.,  3.,  8.,  4.],
        [ 0.,  3.,  4.,  9.,  5.],
        [ 0.,  4.,  5., 10., nan]],

       [[ 1.,  0.,  6., nan,  7.],
        [ 1.,  1.,  7., nan,  8.],
        [ 1.,  2.,  8., nan,  9.],
        [ 1.,  3.,  9., nan, 10.],
        [ 1.,  4., 10., nan, nan]]])
 In [235]: _.reshape(-1,5)           # to get the 2d array  
 ...
0 голосов
/ 07 марта 2020

Я думаю, что лучший способ решить вашу проблему - это использовать циклы for. Приведенный ниже код принимает несколько строк и сохраняет их в словаре.

row1 = [1, 2, 3, 4, 5]
row2 = [6, 7, 8, 9, 10]
row3 = [11, 12, 13, 14, 15]
row4 = [16, 17, 18, 19, 20]
row5 = [21, 22, 23, 24, 25]

def create_array_dict(*args):
    return {row_index: {column_index: value for column_index, value in enumerate(row_list)} for row_index, row_list in enumerate(args)}

arr = create_array_dict(row1, row2, row3, row4, row5)

И после создания словаря мы можем распечатать результаты:

def print_output(arr):
    for row, value in arr.items():
        for column, value in value.items():
            try:
                print(f"Row index={row}, Column Index={column}, Value={value},Value below={arr[row + 1][column]}, Value to the right={arr[row][column + 1]}")
            except:
                try:
                    print(f"Row index={row}, Column Index={column}, Value={value},Value below={arr[row + 1][column]}, Value to the right=None")
                except:
                    try:
                        print(f"Row index={row}, Column Index={column}, Value={value},Value below=None, Value to the right={arr[row][column + 1]}")
                    except:
                        print(f"Row index={row}, Column Index={column}, Value={value},Value below=None, Value to the right=None")

Ouput:

Row index=0, Column Index=0, Value=1,Value below=6, Value to the right=2
Row index=0, Column Index=1, Value=2,Value below=7, Value to the right=3
Row index=0, Column Index=2, Value=3,Value below=8, Value to the right=4
Row index=0, Column Index=3, Value=4,Value below=9, Value to the right=5
Row index=0, Column Index=4, Value=5,Value below=10, Value to the right=None
Row index=1, Column Index=0, Value=6,Value below=11, Value to the right=7
Row index=1, Column Index=1, Value=7,Value below=12, Value to the right=8
Row index=1, Column Index=2, Value=8,Value below=13, Value to the right=9
Row index=1, Column Index=3, Value=9,Value below=14, Value to the right=10
Row index=1, Column Index=4, Value=10,Value below=15, Value to the right=None
Row index=2, Column Index=0, Value=11,Value below=16, Value to the right=12
Row index=2, Column Index=1, Value=12,Value below=17, Value to the right=13
Row index=2, Column Index=2, Value=13,Value below=18, Value to the right=14
Row index=2, Column Index=3, Value=14,Value below=19, Value to the right=15
Row index=2, Column Index=4, Value=15,Value below=20, Value to the right=None
Row index=3, Column Index=0, Value=16,Value below=21, Value to the right=17
Row index=3, Column Index=1, Value=17,Value below=22, Value to the right=18
Row index=3, Column Index=2, Value=18,Value below=23, Value to the right=19
Row index=3, Column Index=3, Value=19,Value below=24, Value to the right=20
Row index=3, Column Index=4, Value=20,Value below=25, Value to the right=None
Row index=4, Column Index=0, Value=21,Value below=None, Value to the right=22
Row index=4, Column Index=1, Value=22,Value below=None, Value to the right=23
Row index=4, Column Index=2, Value=23,Value below=None, Value to the right=24
Row index=4, Column Index=3, Value=24,Value below=None, Value to the right=25
Row index=4, Column Index=4, Value=25,Value below=None, Value to the right=None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...