0

我有一组我想用 numpy 处理的数据。可以将数据视为空间中的一组点,并带有我想作为对象处理的附加属性变量。根据一组数据,向量的长度可能为 1、2 或 3,但对于给定数据集中的所有点,其长度相同。属性对象是一个自定义类,对于任何两个给定点都可能相同。

因此,将此数据视为一个随机示例(C 和 H 表示包含碳或氢的原子属性的对象......或只是一些随机对象)。这些不会通过文件读取,而是由算法创建。这里的 C 对象可能相同,也可能不同(例如同位素)。

Example 3D data set (just abstract representation)
C 1 2 3
C 3 4 5
H 1 1 4

我想要一个包含所有原子位置的 numpy 数组,这样我就可以执行 numpy 操作,如矢量操作和翻译函数def translate(data,vec):return data + vec。我还想并行处理属性对象。一种选择是为两者设置两个单独的数组,但如果我删除一个元素,我也必须显式删除属性数组值。这可能很难处理。

我考虑过使用numpy.recarray

x = np.array([(1.0,2,3, "C"), (3.0,2,3, "H")], dtype=[('x', "float64" ),('y',"float6

4"),('z',"float64"), ('type', object)])

但似乎shape这个数组的 是(2,),这意味着每条记录都是独立处理的。此外,我似乎无法理解如何让矢量操作与这种类型一起工作:

def translate(data,vec):return data + vec
translate(x,np.array([1,2,3]))
...
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.ndarray'

numpy.recarray应该使用什么?有没有更好的方法以更简单的方式处理这个问题,例如我有一个单独的点数值矩阵和一个平行object数组,如果元素被删除(np.delete),它们会链接起来?我还简要地考虑过编写一个 extends 的数组对象ndarray,但我觉得这可能是不必要的并且可能是灾难性的。

任何想法或建议都会非常有帮助。

4

3 回答 3

2

如果将元组作为字段的 dtype 传递,recarray 的字段可以是 ndarray (name, type, shape)

In [9]:

import numpy as np

x = np.array([((1.0,2,3), "C"), ((3.0,2,3), "H")], dtype=[('xyz', "float64", (3,)), ('type', object)])

In [11]:

np.delete(x, 0)

Out[11]:

array([([3.0, 2.0, 3.0], 'H')], 
      dtype=[('xyz', '<f8', (3,)), ('type', 'O')])

In [12]:

x["xyz"]

Out[12]:

array([[ 1.,  2.,  3.],
       [ 3.,  2.,  3.]])

In [14]:

x["xyz"] + (10, 20, 30)

Out[14]:

array([[ 11.,  22.,  33.],
       [ 13.,  22.,  33.]])

对于您的翻译功能:

def translate(data,vec):
    tmp = data.copy()
    tmp["xyz"] += vect
    return tmp

如果你想要更灵活的功能,你可以考虑使用Pandas.DataFrame.

于 2013-03-03T13:16:57.827 回答
1

如果您正在处理原子集合,您可以考虑使用Atomic Simulation Environment (ASE)中的Atoms 类。它存储原子类型、位置并具有类似列表的方法来操作它们。

于 2013-03-03T12:56:59.620 回答
0

一种快速而肮脏的方法是将最后(或实际上任何)列设置为对标签字典的数字查找:

>>> import numpy
>>> labels = ['H', 'C', 'O']
>>> labels_refs = dict(zip(labels, numpy.arange(len(labels), dtype='float64')))
>>> reverse_labels_refs = dict(zip(numpy.arange(len(labels), dtype='float64'), labels))
>>> x = numpy.array([
...     [1.0,2,3, labels_refs['C']], 
...     [3.0,2,3, labels_refs['H']],
...     [2.0,2,3, labels_refs['C']]])
>>> x
array([[ 1.,  2.,  3.,  1.],
       [ 3.,  2.,  3.,  0.],
       [ 2.,  2.,  3.,  1.]])
>>> extract_refs = numpy.vectorize(
...         lambda label_ref: reverse_labels_refs[label_ref])
>>> labels = extract_refs(x[:, -1]) # Turn the last column back into labels
>>> labels
array(['C', 'H', 'C'], 
      dtype='|S8')

您还可以通过标签查找行(例如):

>>> x[numpy.where(x[:,-1] == labels_refs['C']), :-1]
array([[[ 1.,  2.,  3.],
        [ 2.,  2.,  3.]]])
于 2013-03-03T13:00:51.487 回答