Исключение дубликатов со списком Python понимания списка при обращении к нескольким значениям массива - PullRequest
0 голосов
/ 08 января 2020

Задача состоит в том, чтобы вернуть каждую строку набора данных 2D, в которой есть запись, значение которой больше столбца, частью которого она является.

Я пытаюсь выяснить, есть ли более разумный способ сделать это со списком:

data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [86, 4, 14]])
sliced = [data[i] for i in range(len(data))
            for j in range(len(data[i]))
                if data[i,j] > np.mean(data[:,j])]

Этот код возвращает:

[array([7, 8, 9]), array([10, 11, 12]), array([10, 11, 12]), array([13, 14, 15]), array([13, 14, 15]), array([86,  4, 14]), array([86,  4, 14])]

Вы можете видеть, что он выполняет задачу, но оставляет дубликаты в строках, как [10, 11, 12 ] где оба значения 11 и 12 превышают среднее значение их столбцов.

Есть ли умный способ исключить дополнительные точки данных из одной строки во время понимания списка? Я мог бы удалить дубликаты позже, но в гипотетическом контексте, который мог бы удалить действительные данные, которые оказались идентичными.

1 Ответ

0 голосов
/ 08 января 2020
In [45]: data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14
    ...: , 15], [86, 4, 14]])                                                   
In [46]: data                                                                   
Out[46]: 
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12],
       [13, 14, 15],
       [86,  4, 14]])

In [49]: [data[i] for i in range(len(data)) 
    ...:             for j in range(len(data[i])) 
    ...:                 if data[i,j] > np.mean(data[:,j])]                     
Out[49]: 
[array([7, 8, 9]),
 array([10, 11, 12]),
 array([10, 11, 12]),
 array([13, 14, 15]),
 array([13, 14, 15]),
 array([86,  4, 14]),
 array([86,  4, 14])]

Я намеревался получить правильное понимание списка, но затем понял, что к нему проще подходить с точки зрения numpy:

In [55]: m = data.mean(axis=0)                                                  
In [56]: m                                                                      
Out[56]: array([20.16666667,  7.33333333,  9.83333333])
In [57]: data>m                                                                 
Out[57]: 
array([[False, False, False],
       [False, False, False],
       [False,  True, False],
       [False,  True,  True],
       [False,  True,  True],
       [ True, False,  True]])
In [58]: np.any(data>m, axis=1)                                                 
Out[58]: array([False, False,  True,  True,  True,  True])
In [59]: data[_,:]                                                              
Out[59]: 
array([[ 7,  8,  9],
       [10, 11, 12],
       [13, 14, 15],
       [86,  4, 14]])

Версия понимания списка:

In [64]: [row for row in data if any(row > m)]                                  
Out[64]: 
[array([7, 8, 9]),
 array([10, 11, 12]),
 array([13, 14, 15]),
 array([86,  4, 14])]

, хотя все еще используется тест numpy row>m. Сложность с подходом чистого списка состоит в том, что ваше желаемое значение убирается по столбцам.

[row for row in data ... if ... mean(row)]

не работает, потому что это неправильное измерение; мы хотим mean(col) или как вы data[:,j].

...