将对象列表转换为 numpy 数组而不将对象强制转换为数组
Convert list of objects to numpy array without coercing objects into array
我想将一个 Python 对象列表转换为一个 numpy 对象数组,以便于对列表进行操作,例如索引切片等。但是,numpy 在转换过程中将类似列表的对象强制转换为数组
import numpy as np
class ListLike(object):
def __init__(self, list):
self.list = list
self.otherdata = 'foo'
def __getitem__(self, i):
return self.list[i]
def __len__(self):
return len(self.list)
o1 = ListLike([1,2])
o2 = ListLike([3,4])
listOfObj = [o1, o2]
numpyArray = np.array(listOfObj)
>>> numpyArray
array([[1, 2],
[3, 4]])
>>> type(numpyArray[0])
<class 'numpy.ndarray'>
这意味着我丢失了对象以及与之关联的其他数据和方法
>>> numpyArray[0].otherdata
AttributeError: 'numpy.ndarray' object has no attribute 'otherdata'
我如何得到这个结果?
>>> numpyArray
array([(<__main__.ListLike object at 0x000000002786DAF0>, <__main__.ListLike object at 0x000000002E56B700>)], dtype=object)
>>> type(numpyArray[0])
<class '__main__.ListLike'>
如果我也能像这样控制强制的深度就更好了
o3 = ListLike([o1,o2])
numpyArray = np.array([o3, o3], depth=1)
>>> numpyArray
array([[(<__main__.ListLike object at 0x000000002786DAF0>, <__main__.ListLike object at 0x000000002E56B700>)], [(<__main__.ListLike object at 0x000000002786DAF0>, <__main__.ListLike object at 0x000000002E56B700>)]], dtype=object)
In [35]: arr = np.empty(2, object)
In [36]: arr[:] = listOfObj
In [37]: arr
Out[37]:
array([<__main__.ListLike object at 0x7f3b9c6f1df0>,
<__main__.ListLike object at 0x7f3b9c6f19d0>], dtype=object)
元素 methods/attributes 必须通过列表理解来访问,就像列表一样:
In [39]: arr[0].otherdata
Out[39]: 'foo'
In [40]: [a.otherdata for a in listOfObj]
Out[40]: ['foo', 'foo']
In [41]: [a.otherdata for a in arr]
Out[41]: ['foo', 'foo']
frompyfunc
也可以用于此,但时间大致相同:
In [44]: np.frompyfunc(lambda a: a.otherdata,1,1)(arr)
Out[44]: array(['foo', 'foo'], dtype=object)
我认为你希望实现这个:
class ListLike(np.array):
def __init__(self, _list):
super().__init__(_list)
self.otherdata = 'foo'
但是你不能从 builtin_function.. subclass,尽管你可以尝试从 np.ndarray
相反,我设法写了
class ListLike(object):
def __init__(self, _list):
self._list = _list
self.otherdata = 'foo'
def __getitem__(self, key): return self._list[key]
def __str__(self): return self._list.__str__()
#Note 1
#def __len__(self): return self._list.__len__()
测试:
o1 = ListLike([1,2])
o2 = ListLike([3,4])
numpyArray = np.array([o1, o2], dtype=object)
#Note 2
#numpyArray = np.array([o1, o2, 888], dtype=object)
print(numpyArray[0], numpyArray[0].otherdata, end='.\t')
print("Expected: [1,2] foo")
注1
只要您不为 LikeList class 实现 __len__ 方法,此方法就有效。
注2
如果您坚持,请将某种巫术附加到这一行。
- 空项目如:'',None, []
- 另一个暗淡的实例为:LikeList([7])
- 另一个对象为:5,...(省略号),'hello',0.1
(我想不通,为什么 np.array 没有检测到 dtype=object)
我想将一个 Python 对象列表转换为一个 numpy 对象数组,以便于对列表进行操作,例如索引切片等。但是,numpy 在转换过程中将类似列表的对象强制转换为数组
import numpy as np
class ListLike(object):
def __init__(self, list):
self.list = list
self.otherdata = 'foo'
def __getitem__(self, i):
return self.list[i]
def __len__(self):
return len(self.list)
o1 = ListLike([1,2])
o2 = ListLike([3,4])
listOfObj = [o1, o2]
numpyArray = np.array(listOfObj)
>>> numpyArray
array([[1, 2],
[3, 4]])
>>> type(numpyArray[0])
<class 'numpy.ndarray'>
这意味着我丢失了对象以及与之关联的其他数据和方法
>>> numpyArray[0].otherdata
AttributeError: 'numpy.ndarray' object has no attribute 'otherdata'
我如何得到这个结果?
>>> numpyArray
array([(<__main__.ListLike object at 0x000000002786DAF0>, <__main__.ListLike object at 0x000000002E56B700>)], dtype=object)
>>> type(numpyArray[0])
<class '__main__.ListLike'>
如果我也能像这样控制强制的深度就更好了
o3 = ListLike([o1,o2])
numpyArray = np.array([o3, o3], depth=1)
>>> numpyArray
array([[(<__main__.ListLike object at 0x000000002786DAF0>, <__main__.ListLike object at 0x000000002E56B700>)], [(<__main__.ListLike object at 0x000000002786DAF0>, <__main__.ListLike object at 0x000000002E56B700>)]], dtype=object)
In [35]: arr = np.empty(2, object)
In [36]: arr[:] = listOfObj
In [37]: arr
Out[37]:
array([<__main__.ListLike object at 0x7f3b9c6f1df0>,
<__main__.ListLike object at 0x7f3b9c6f19d0>], dtype=object)
元素 methods/attributes 必须通过列表理解来访问,就像列表一样:
In [39]: arr[0].otherdata
Out[39]: 'foo'
In [40]: [a.otherdata for a in listOfObj]
Out[40]: ['foo', 'foo']
In [41]: [a.otherdata for a in arr]
Out[41]: ['foo', 'foo']
frompyfunc
也可以用于此,但时间大致相同:
In [44]: np.frompyfunc(lambda a: a.otherdata,1,1)(arr)
Out[44]: array(['foo', 'foo'], dtype=object)
我认为你希望实现这个:
class ListLike(np.array):
def __init__(self, _list):
super().__init__(_list)
self.otherdata = 'foo'
但是你不能从 builtin_function.. subclass,尽管你可以尝试从 np.ndarray
相反,我设法写了
class ListLike(object):
def __init__(self, _list):
self._list = _list
self.otherdata = 'foo'
def __getitem__(self, key): return self._list[key]
def __str__(self): return self._list.__str__()
#Note 1
#def __len__(self): return self._list.__len__()
测试:
o1 = ListLike([1,2])
o2 = ListLike([3,4])
numpyArray = np.array([o1, o2], dtype=object)
#Note 2
#numpyArray = np.array([o1, o2, 888], dtype=object)
print(numpyArray[0], numpyArray[0].otherdata, end='.\t')
print("Expected: [1,2] foo")
注1
只要您不为 LikeList class 实现 __len__ 方法,此方法就有效。
注2
如果您坚持,请将某种巫术附加到这一行。
- 空项目如:'',None, []
- 另一个暗淡的实例为:LikeList([7])
- 另一个对象为:5,...(省略号),'hello',0.1
(我想不通,为什么 np.array 没有检测到 dtype=object)