Numpy:ndarray中行的元组索引(用于以后选择的子集)

时间:2016-01-27 20:09:11

标签: python arrays numpy indexing

我是NumPy的新手,也不是最有成就感的Python程序员, 如果这对你来说似乎微不足道,请原谅我;)

我正在编写一个脚本,用于从几个分子动力学模拟中提取特定数据。 因此,我从一些文件中读取数据并将其修改并截断为统一长度 并将所有内容逐行添加,以形成每个模拟运行的2D数组。

这些数组相互附加,因此我最终得到一个3D数组,其中沿z轴的每个切片将代表特定模拟运行的数据集。 目标是稍后进行简单的操作,例如平均所有模拟运行。

这只是为了让您了解所做的事情的基本概念:

import numpy as np

A = np.zeros((2000), dtype = bool)
A = A.reshape((1, 2000))

# Appending different rows to form a '2D-Matrix', 
# this is the actual data per simulation run
for i in xrange(1,103):
    B = np.zeros((2000), dtype = bool)
    B = B.reshape((1, 2000))
    A = np.concatenate((A, B), axis=0)

print A.shape
# >>> (2000, 103)

C = np.expand_dims(A, axis=2)
A = np.expand_dims(A, axis=2)

print A.shape
# >>> (2000, 103, 1)

# Appending different '2D-Matrices' to form a 3D array, 
# each slice along the z-Axis representing one simulation run
for i in xrange(1,50):
    A = np.concatenate((A, C), axis=2) 

print A.shape
# >>> (2000, 103, 50)

到目前为止一直很好,现在对实际问题:

在一个2D数组中,每一行代表一组不同的相互作用原子对。 我后来想要创建数组的子集,具体取决于不同的标准 - 例如'给我看所有对,其中距离x是10&lt; x <= 20'。

因此,当我第一次在for i in xrange(1,103): ...中添加行时,我希望为每行包含一组 int 的行的索引。 无论如何,原子对的数据都存在,目前我还没有将它包含在ndarray中。

我在想一个元组,所以我的2D数组看起来像

[ [('int' a,'int' b), [False,True,False,...]],
  [('int' a,'int' d), [True, False, True...]],
 ...
]

或类似的东西

[ [['int' a], ['int' b], [False,True,False,...]],
  [['int' a], ['int' d], [True, False, True...]],
 ...
]

您能想到这种过滤的另一种或更简单的方法吗? 我不太确定我是否在这里正确的轨道,并且在这样的数组中使用不同的数据类型似乎并不是非常简单。

另请注意,所有索引在每个2D数组中都以相同的方式排序,因为我对它们进行排序( atm 基于String)并为那些添加np.zeros()行仅在其他模拟运行中发生。 也许Lookup-table是正确的做法?

非常感谢!

1 个答案:

答案 0 :(得分:0)

更新/答案:

对不起,我知道这个问题有点过于具体和臃肿了 与问题无关的代码。

我自己回答了这个问题,为了便于记录,您可以在下面找到它。它具体,但可能有助于某人在numpy中处理他的索引。

简短,一般回答:

我基本上只是创建了一个查找表作为python列表,并使用掩码进行了一个非常简单的numpy切片操作,包含索引:

A = [[[1, 2],
      [3, 4],
      [5, 6]],

     [[7, 8],
      [9,10],
      [11,12]]]
A = np.asarray(A)

# selects only rows 1 and 2 from each 2D array
mask = [1,2]
B = A[ : , mask, : ]

给出了B

[[[ 3  4]
  [ 5  6]]

 [[ 9 10]
  [11 12]]]

完整答案,具体针对上述问题:

这是我的2D数组:

A =[[True, False, False, False, False],
    [False, True, False, False, False],
    [False, False, True, False, False]]
A = np.asarray(A)

将行索引为元组,这是由于我的具体问题  e.g:

lut = [(1,2),(3,4),(3,5)]

追加其他2D数组以形成3D数组:

C = np.expand_dims(A, axis=0)
A = np.expand_dims(A, axis=0)

A = np.concatenate((A, C), axis=0) 

这是3D数组A

 >[[[ True False False False False]
    [False  True False False False]
    [False False  True False False]]

   [[ True False False False False]
    [False  True False False False]
    [False False  True False False]]]

在查找表

中选择包含“3”的行
mask = [i for i, v in enumerate(lut) if 3 in v] 

> [1, 2]

将蒙版应用于3D阵列:

B = A[ : , mask, : ]

现在B是选择后的3D数组A

[[[False  True False False False]
   [False False  True False False]]

  [[False  True False False False]
   [False False  True False False]]]

跟踪B的新索引: 创建一个新的查找表以进行进一步计算:

newLut = [v for i, v in enumerate(lut) if i in mask] 

>[(3, 4), (3, 5)]