繁体   English   中英

合并NumPy数组并在Python中查找列

[英]Merging NumPy arrays and finding columns in Python

我是Python的新手。 我有两个CSV格式的数据文件。 我将CSV文件数据加载到两个NumPy数组中:

matrix1 = numpy.genfromtxt(fileName1)
matrix2 = numpy.genfromtxt(fileName2)

两个矩阵的行和列不相等。

>>print(matrix1.shape)
(971, 4413)
>>print(matrix2.shape)
>>(5504, 4431)

我想以这种方式组合matrix1和matrix2:

mergedMatrix = [ matrix1, matrix2 ]

哪里可以访问matrix1mergedMatrix使用指数0matrix2使用索引1

我尝试使用numpy.concatenate但不适用于这两个矩阵。 所以我试图用熊猫转换后合并功能matrix1matrix2到大熊猫DataFrames。 但是,这样做花了很多时间,并且所有矩阵都合并到单个线性数组中,例如[1, 2, 3,4,5...] ,我没有任何方法可以区分matrix1matrix2mergedMatrix

所以我正在使用:

#mergedMatrix as a list
mergedMatrix = [matrix1, matrix2]

我的数据包含Inf值。 如果一列在matrix1包含值Inf ,那么我想删除该列以及对应的列,即在matrix2具有相同列号的列。

问题

  1. 有没有比使用列表mergedMatrix更好的方法?
  2. 如何快速查找matrix1列是否包含此类值,而无需一一检查每个元素及其列号?

例:

matrix1 = [[1, 2, 3],
           [3, inf,0],
           [2 , inf, inf]]
matrix2 = [[0, 4, 2, 7],
           [0, 1, 0.5, 3],
           [1, 2, 3, 9]]

mergedMatrix = [[1, 2, 3],
           [3, inf,0],
           [2 , inf, inf],
           [0, 4, 2, 7],
           [0, 1, 0.5, 3],
           [1, 2, 3, 9]]

结果应为:

mergedMatrix = [[1],
                [3],
                [2],
                [0,7],
                [0,3],
                [1,9]]

removedMatrixCols = [[2, 3],
               [inf,0],
               [inf, inf],
               [4, 2],
               [1, 0.5],
               [2, 3]]

然后,我想分割矩阵:

newMatrix1 = [[1],
              [3],
              [2]]
newMatrix2 = [[0,7],
              [0,3],
              [1,9]]

removedCols1 = [[2, 3],
                [inf,0],
                [inf, inf]]

removedCols2 = [[4, 2],
                [1, 0.5],
                [2, 3]]

这样我就可以将它们分别存储到CSV文件中。

简而言之,答案是:从技术上讲是,但不是,不是,是。

1:如果需要3-D列表,则应使用列表,但我也将其放入数组( mergedMatrix = numpy.array([matrix1, matrix2]) )中,以便仍可以按元素使用-新矩阵中的元素逻辑

2 :(注意:这些是完全不同的问题,因此,严格来讲,与合并为一个问题相比, 应该在2个不同的问题中提出问题,但我可以生存)

为此,您可以使用numpy.delete删除列。 要删除列,请使用axis=1 arg,例如:

new_mat = numpy.delete(mergedMatrix, cols_to_delete, axis=1)

其中mergedMatrix和cols_to_delete都是数组。

您可以使用numpy.isinf ,而不是使用嵌套的for循环遍历数组来查找包含Inf编号的列,然后可以从上方替换cols_to_delete (*注:cols_to_delete = numpy.isinf(merged_Matrix)[:, 1]

无论如何,希望这会有所帮助! 干杯

我可以想到四种解决方案:

  • 像在问题中一样使用列表。 没有什么不妥。 而且您可以按list[0][xx:yy]索引数组list[0][xx:yy]

  • 将数据存储在{1:matrix1,2:matrix2}之类的字典中

  • 如果您确实想使用熊猫,则必须在数据合并之前添加一个标识符列(data1,data2),然后可以使用groupy对数据进行groupy或设置索引df.set_index('id_column') 但是我认为那太过分了。

  • 如果您使用np.vstacknp.hstack (取决于它们相等的轴,则将丢失哪个矩阵是哪个信息。除非您生成具有布尔ID的掩码,例如

    mask = np.ones(len(merged_matrix)) mask[0:len(matrix1)] = 0

假设您实际上并不需要mergedMatrix ,这是在不显式构造mergedMatrix情况下获取newMatrix1newMatrix2removedCols1removedCols2 mergedMatrix

找到有趣的价值

首先,让我们查找inf条目:

import numpy as np
matrix1 = np.genfromtxt(fileName1)
matrix2 = np.genfromtxt(fileName2)

matrix1_infs = matrix1 == float('inf')

# or if you want to treat -inf the same as inf:
matrix1_infs = np.isinf(matrix1)

这为您提供了一个布尔2D NumPy数组。 对于您的小型示例数组,它将是

array([[False, False, False],
       [False,  True, False],
       [False,  True,  True]], dtype=bool)

煮沸成柱

您对单个元素不感兴趣,但是哪些列具有任何inf值。 直接找出答案的方法是使用

matrix1_inf_columns = matrix1_infs.any(axis=0)

使用线性代数和布尔代数的组合来得出以下向量矩阵乘积会更加晦涩:

matrix1_inf_columns = np.dot(np.repeat(True, matrix1.shape[1]), matrix1_infs)

结果是一样的:

array([False,  True,  True], dtype=bool)

使用布尔索引数组进行切片

当您将布尔值NumPy数组用作其他NumPy数组的索引时 ,会发生一些有趣的事情:

>>> matrix1[:, matrix1_inf_columns] # First index is rows, second columns.
                                    # : means all. Thus here:
                                    # All rows, but only the selected columns.
array([[  2.,   3.],
       [ inf,   0.],
       [ inf,  inf]])

尼斯。 这就是我们想要的removedCols1 但是它变得更加疯狂。 当您采用布尔数组的负数时会发生什么?

>>> -matrix1_inf_columns
array([ True, False, False], dtype=bool)

NumPy否定其元素! 这意味着我们可以将newMatrix1作为

newMatrix1 = matrix1[:, -matrix1_inf_columns]
# array([[ 0.],
#        [ 0.],
#        [ 1.]])

当然,布尔索引数组并不知道它最初是由matrix1构造的,因此我们可以很容易地使用它来索引matrix2

removedCols2 = matrix2[:, matrix1_inf_columns]
# array([[ 4. ,  2. ],
#        [ 1. ,  0.5],
#        [ 2. ,  3. ]])

但是,如果布尔索引数组的长度小于索引数组的维数,则对于缺少的布尔索引,它将假定False

>>> matrix2[:, -matrix1_inf_columns]
array([[ 0.],
       [ 0.],
       [ 1.]])

那不是我们想要的完整newMatrix2

尺寸麻烦

因此,我们必须使用更大的索引数组。

>>> matrix1_inf_columns.resize(matrix2.shape[1])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot resize an array references or is referenced
by another array in this way.  Use the resize function

噢。 resize功能 文档说,当请求的大小大于数组时,它将(除了我尝试在此处使用的resize NumPy数组resize方法)不填充零(对于布尔数组,则为False ),而是重复数组。

因此,让我们看看是否可以获得深层副本,而不是在matrix1上的视图:

>>> tmp = matrix1_inf_columns.copy()
>>> tmp.resize(matrix2.shape[1])
>>> tmp
array([False,  True,  True, False], dtype=bool)
>>> -tmp
array([ True, False, False,  True], dtype=bool)

好的,那行得通。 让我们将其作为matrix2的索引插入。

removedCols2 = matrix2[:, tmp]
# array([[ 4. ,  2. ],
#        [ 1. ,  0.5],
#        [ 2. ,  3. ]])

很好,所以仍然有效。

newMatrix2 = matrix2[:, -tmp]
# array([[ 0.,  7.],
#        [ 0.,  3.],
#        [ 1.,  9.]])

好极了!

要无限 超越

如果您还希望将matrix2无限值考虑在内以进行过滤,或者您的实际情况更加复杂,则情况将更加复杂。 但是您现在已经了解了所需的大多数概念。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM