【问题标题】:MinMax Scale Sparse Matrix Excluding Zero ElementsMinMax 比例稀疏矩阵不包括零元素
【发布时间】:2019-01-05 07:40:19
【问题描述】:

我有一个矩阵,其中包含 [0, 5] 之间的数字。矩阵非常稀疏,大部分元素为零。我想分别对每一行应用最小-最大缩放,使所有元素都在 [-1, 1] 之间。但是,我只想考虑非零元素。例如,考虑以下矩阵:

[[0.5 3.  0.  2.  0. ]
 [0.  4.  5.  0.  0. ]
 [3.  0.  0.  2.5 4. ]]

转换后的样子:(如你所见,0个元素未被触及)

[[-1.          1.          0.          0.2         0.        ]
 [ 0.         -1.          1.          0.          0.        ]
 [-0.33333333  0.          0.         -1.          1.        ]]

我可以使用以下代码对普通的 numpy 数组执行此操作:

max_arr = A.max(axis=1)
min_arr = np.where(A == 0, A.max(), A).min(axis=1)
row_idx, col_idx = A.nonzero()
A_scaled = np.zeros_like(A)
for row, col in zip(row_idx, col_idx):
    element = A[row, col]
    A_scaled[row, col] = 2 * ((element - min_arr[row]) / (max_arr[row] - min_arr[row])) - 1

这里有几个问题。首先,它很慢(可能是因为 for 循环?)。另一件事是我的矩阵是稀疏的,所以我想使用稀疏的csr_matrix 格式。如果矩阵Acsr_matrix,则此代码不起作用。它在第 2 行给出错误说 ValueError: setting an array element with a sequence.

我怎样才能以一种快速且节省内存的方式实现这一目标?我查看了sklearn.preprocessing.MinMaxScaler,但它不支持通过排除零来进行缩放。

【问题讨论】:

  • @Divakar,是的。抱歉,回复晚了,直到现在我才抽出时间尝试您的代码。它就像一个魅力,它肯定要快得多。谢谢。

标签: python numpy scipy


【解决方案1】:

这是csr_matrix 矩阵的一种矢量化方法 -

def scale_sparse_matrix_rows(s, lowval=0, highval=1):
    d = s.data

    lens = s.getnnz(axis=1)
    idx = np.r_[0,lens[:-1].cumsum()]

    maxs = np.maximum.reduceat(d, idx)
    mins = np.minimum.reduceat(d, idx)

    minsr = np.repeat(mins, lens)
    maxsr = np.repeat(maxs, lens)

    D = highval - lowval
    scaled_01_vals = (d - minsr)/(maxsr - minsr)
    d[:] = scaled_01_vals*D + lowval

示例运行 -

1) 设置输入 csr_matrix :

In [153]: a
Out[153]: 
array([[0.5, 3. , 0. , 2. , 0. ],
       [0. , 4. , 5. , 0. , 0. ],
       [3. , 0. , 0. , 2.5, 4. ]])

In [154]: from scipy.sparse import csr_matrix

In [155]: s = csr_matrix(a)

2) 运行建议的方法并验证结果:

In [156]: scale_sparse_matrix_rows(s, lowval=-1, highval=1)

In [157]: s.toarray()
Out[157]: 
array([[-1.        ,  1.        ,  0.        ,  0.2       ,  0.        ],
       [ 0.        , -1.        ,  1.        ,  0.        ,  0.        ],
       [-0.33333333,  0.        ,  0.        , -1.        ,  1.        ]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多