Найти наибольшее значение из нескольких столбцов в каждой группе индекса строки в Python, расположить эти значения по диагонали в матрице и найти определитель - PullRequest
2 голосов
/ 23 мая 2019

Я новичок в Python.Я хочу найти самые большие значения из всех столбцов для повторяющихся индексов строк (то есть от 5 до 130), а также показать его метку строки и индекса столбца в выходных данных. Самые большие значения должны быть абсолютными.(Независимо от знака + или -).Не должно быть дубликатов для индексов строк в разных группах.После нахождения наибольшего значения в каждой группе я хочу расположить эти значения по диагонали в квадратной матрице.Затем заполните оставшийся массив соответствующими значениями индексов для каждой группы из основного кадра данных и найдите его определитель.

df=pd.DataFrame(
    {'0_deg': [43, 50, 45, -17, 5, 19, 11, 32, 36, 41, 19, 11, 32, 36, 1, 19, 7, 1, 36, 10], 
     '10_deg': [47, 41, 46, -18, 4, 16, 12, 34, -52, 31, 16, 12, 34, -71, 2, 9, 52, 34, -6, 9], 
     '20_deg': [46, 43, -56, 29, 6, 14, 13, 33, 43, 6, 14, 13, 37, 43, 3, 14, 13, 25, 40, 8], 
     '30_deg': [-46, 16, -40, -11, 9, 15, 33, -39, -22, 21, 15, 63, -39, -22, 4, 6, 25, -39, -22, 7]
    }, index=[5, 10, 12, 101, 130, 5, 10, 12, 101, 130, 5, 10, 12, 101, 130, 5, 10, 12, 101, 130]
)

Набор данных:

data

Ожидаемый результат:

op1

Мой код отображается только до выхода 1.

op2

op3

Фактический выход:

actop

Код:

df = pd.read_csv ('Matrixfile.csv')
df = df.set_index('Number')

def f(x):
    x1 = x.abs().stack()
    x2 = x.stack()
    x = x2.iloc[np.argsort(-x1)].head(1)
    return x

groups = (df.index == 5).cumsum()
df1 = df.groupby(groups).apply(f).reset_index(level=[1,2])
df1.columns = ['Number','Angle','Value']

print (df1)
df1.to_csv('Matrix_OP.csv', encoding='utf-8', index=True)

1 Ответ

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

Я не уверен насчет вывода @piRSquared из того, что я понял из вашего вопроса.Там могут быть некоторые ошибки, например, в группе 2 max (abs (значения)) = 52 (подчеркивание красным на рисунке), но 41 отображается слева ...

Вот меньшеэлегантный способ сделать это, но, возможно, вам будет проще понять:

import numpy as np

# INPUT
data_dict ={'0_deg': [43, 50, 45, -17, 5, 19, 11, 32, 36, 41, 19, 11, 32, 36, 1, 19, 7, 1, 36, 10], 
   '10_deg': [47, 41, 46, -18, 4, 16, 12, 34, -52, 31, 16, 12, 34, -71, 2, 9, 52, 34, -6, 9], 
   '20_deg': [46, 43, -56, 29, 6, 14, 13, 33, 43, 6, 14, 13, 37, 43, 3, 14, 13, 25, 40, 8], 
   '30_deg': [-46, 16, -40, -11, 9, 15, 33, -39, -22, 21, 15, 63, -39, -22, 4, 6, 25, -39, -22, 7],
   }

# Row idx of a group in this list
idx = [5, 10, 12, 101, 130]


# Getting some dimensions and sorting the data
row_idx_length = len(idx) 
group_length = len(data_dict['0_deg'])
number_of_groups = len(data_dict.keys())  
idx = idx*number_of_groups   
data_arr = np.zeros((group_length,number_of_groups),dtype=np.int32) 
#
col = 0
keys = []
for key in sorted(data_dict):
    data_arr[:,col] = data_dict[key]
    keys.append(key)
    col+=1
def get_extrema_value_group(arr):
    # function to find absolute extrema value of a 2d array
    extrema = 0
    for i in range(0, len(arr)):
        max_value = max(arr[i])
        min_value = min(arr[i])
        if (abs(min_value) > max_value) and (abs(extrema) < abs(min_value)):
            extrema = min_value
        elif (abs(min_value) < max_value) and (abs(extrema) < max_value):
            extrema = max_value         
    return extrema 

# For output 1
max_values = []  
for i in range(0,row_idx_length*number_of_groups,row_idx_length):
    # get the max value for the current group
    value = get_extrema_value_group(data_arr[i:i+row_idx_length])
    # get the row and column idx associated with the max value
    idx_angle_number = np.nonzero(abs(data_arr[i:i+row_idx_length,:])==value)
    print('Group number : ' + str(i//row_idx_length+1))
    print('Number : '+ str(idx[idx_angle_number[0][0]]))
    print('Angle : '+ keys[idx_angle_number[1][0]])
    print('Absolute extrema value : ' + str(value))   
    print('------')
    max_values.append(value)

# Arrange those values diagonally in square matrix for output 2
A = np.diag(max_values)   
print('A = ' + str(A))

# Fill A with desired values
for i in range(0,number_of_groups,1):
    A[i,0] = data_arr[i*row_idx_length+2,2]   # 20 deg 12
    A[i,1:3] = data_arr[i*row_idx_length+3,1] # x2 : 10 deg 101
    A[i,3] = data_arr[i*row_idx_length+1,1]   # 10 deg 10

# Final output
# replace the diagonal of A with max values
# get the idx of diag
A_di = np.diag_indices(number_of_groups)
# replace with max values
A[A_di] = max_values
print ('A = ' + str(A)) 

# Compute determinant of A
det_A = np.linalg.det(A)
print ('det(A) = '+str(det_A))

Выход 1:

Group number : 1
Number : 12
Angle : 20_deg
Absolute extrema value : -56
------
Group number : 2
Number : 101
Angle : 10_deg
Absolute extrema value : -52
------
Group number : 3
Number : 101
Angle : 10_deg
Absolute extrema value : -71
------
Group number : 4
Number : 10
Angle : 10_deg
Absolute extrema value : 52
------

Выход 2:

A = [[-56  0  0  0]
     [ 0 -52  0  0]
     [ 0  0 -71  0]
     [ 0  0  0  52]]

Выход 3:

A = [[-56 -18 -18  41]
     [ 33 -52 -52  12]
     [ 37 -71 -71  12]
     [ 25  -6  -6  52]]

det(A) = -5.4731330578761246e-11
...