我有一组数据,我想用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
),它们会被链接?我还简要地考虑过编写一个扩展ndarray
的数组对象,但我觉得这可能是不必要的,也可能是灾难性的。
任何想法或建议都会非常有用。
答案 0 :(得分:2)
如果你将元组(name, type, shape)
作为字段的dtype传递,则重新排列的字段可以是ndarray:
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
。
答案 1 :(得分:1)
如果您正在处理原子集合,可以考虑使用Atoms class中的Atomic Simulation Environment (ASE)。它存储原子类型,位置,并具有类似列表的方法来操纵它们。
答案 2 :(得分: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.]]])