Обновление записей в матрице при определенных условиях - PullRequest
0 голосов
/ 11 января 2019

У меня есть матрица, которая выглядит так:

[[1.10629335 0.         2.21258671 ... 0.         0.         0.        ]
 [0.         0.         0.         ... 0.         0.         0.        ]
 [1.25571599 1.25571599 0.         ... 0.         0.         0.        ]
 ...
 [1.         1.41956932 1.49244153 ... 0.         0.         0.        ]
 [0.         0.         0.         ... 2.10342705 0.         1.05171352]
 [0.         0.         0.         ... 0.         0.         0.        ]]

Я хочу просмотреть каждую строку и проверить, меньше ли запись, чем 1, если это так, тогда я беру эту запись и добавляю запись справа от нее. Например, предположим, у меня есть

[[ 0.5 ,  1]
 [0  ,   0]]

Первая запись - 0.5, что меньше 0, поэтому теперь у нас будет

[[ 1.5 ,  1]
 [0  ,   0]]

Я думаю, это делает пример относительно ясным. Теперь, как мне применить это ко всей имеющейся у меня матрице?

Вот что я попробовал:

def modify_PITI_nums(adjusted_PITI_nums1):
    for i in range(1,col_num):
        if adjusted_PITI_nums1.iloc[0][i] <1:

            return  adjusted_PITI_nums1.iloc[:,i]+ (adjusted_PITI_nums1.iloc[:,i+1] -1)
        else:
            return adjusted_PITI_nums1.iloc[:,i]



adjusted_PITI_nums1.apply(lambda row: modify_PITI_nums(row['nper_0']), axis = 1)

Но я получаю эту ошибку:

AttributeError: ("'numpy.float64' object has no attribute 'iloc'", 'occurred at index a1')

Обратите внимание, что adjusted_PITI_nums1 - это кадр данных с содержимым матрицы, а заголовки выглядят так:

enter image description here

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Вот решение только для NumPy, которое должно работать:

In [51]: arr  
Out[51]: 
array([[0.5, 1. ],
       [0. , 0. ]])

# generate a boolean mask
In [52]: mask = (arr < 1)
Out[52]: 
array([[ True, False],
       [ True,  True]])

# go over all the columns and check for condition
In [53]: for col in range(mask.shape[1]): 
    ...:     if np.all(mask[:, col]): 
    ...:         arr[:, col] = arr[:, col] + arr[:, col+1] 
    ...:     else: 
    ...:         continue 

In [54]: arr          
Out[54]: 
array([[1.5, 1. ],
       [0. , 0. ]])

Примечание. При таком подходе предполагается, что все значения в определенном столбце меньше значений в правой части.

0 голосов
/ 11 января 2019

Вот пример:

def modify_row(row):
    for i in range(len(row)-1):
        if row[i] < 0.5:
            row[i] += row[i+1]
    return row    

df = df.apply(lambda row: modify(row), axis=1)

ввод:

        0          1           2          3
0   0.939943    0.891797    0.491610    0.827307
1   0.500028    0.756851    0.545806    0.575469
2   0.880074    0.662705    0.205046    0.269572
3   0.970287    0.731664    0.528683    0.785946

дает:

        0           1           2           3
0   0.939943    0.891797    1.318918    0.827307
1   0.500028    0.756851    0.545806    0.575469
2   0.880074    0.662705    0.474618    0.269572
3   0.970287    0.731664    0.528683    0.785946

Обратите внимание на входные данные в столбце 2.


Редактировать: DataFrame.transform() является лучшим кандидатом, поскольку он не создает новый фрейм данных. Также работает параллель, как kmario23:

def modify_row(row):
    mask = row[:-1] < 0.5
    row[:-1] += row[1:]* mask

# raw = True makes row to be an np.array
df.transform(lambda row: modify_row(row), axis=1, raw=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...