来自 uproot 的字符串数组
Arrays of strings from uproot
我有一棵树,其中一个树枝存储着一个字符串。
当我阅读使用 uproot.open()
然后阅读方法 arrays()
时,我得到以下信息:
>>> array_train['backtracked_end_process']
<ObjectArray [b'FastScintillation' b'FastScintillation' b'FastScintillation' ... b'FastScintillation' b'FastScintillation' b'FastScintillation'] at 0x7f48936e6c90>
我想用这个分支来创建面具,通过做一些事情
array_train['backtracked_end_process'] != b'FastScintillation'
但不幸的是,这会产生一个错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-97-a28f3706c5b5> in <module>
----> 1 array_train['backtracked_end_process'] == b'FastScintillation'
~/.local/lib/python3.7/site-packages/numpy/lib/mixins.py in func(self, other)
23 if _disables_array_ufunc(other):
24 return NotImplemented
---> 25 return ufunc(self, other)
26 func.__name__ = '__{}__'.format(name)
27 return func
~/.local/lib/python3.7/site-packages/awkward/array/objects.py in __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
216 contents.append(x)
217
--> 218 result = getattr(ufunc, method)(*contents, **kwargs)
219
220 if self._util_iscomparison(ufunc):
~/.local/lib/python3.7/site-packages/awkward/array/jagged.py in __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
987 data = self._util_toarray(inputs[i], inputs[i].dtype)
988 if starts.shape != data.shape:
--> 989 raise ValueError("cannot broadcast JaggedArray of shape {0} with array of shape {1}".format(starts.shape, data.shape))
990
991 if parents is None:
ValueError: cannot broadcast JaggedArray of shape (24035,) with array of shape ()
有人对如何进行有任何建议吗?能够将其转换为 numpy.chararray
已经可以解决问题,但我不知道该怎么做。
字符串处理是 uproot 中的一个弱点。它使用自定义 ObjectArray
(甚至不是笨拙数组中的 StringArray
),按需生成 bytes
对象。你想要的是一个 class 的字符串数组 ==
重载意味着 "compare each variable-length string, broadcasting a single string to an array if necessary." 不幸的是,无论是根 ObjectArray
的字符串还是 StringArray
class 在笨拙的数组中这样做吧。
诚然,这是通过隐式 Python for 循环实现的方法。
>>> import uproot, numpy
>>> f = uproot.open("http://scikit-hep.org/uproot/examples/sample-6.10.05-zlib.root")
>>> t = f["sample"]
>>> t["str"].array()
<ObjectArray [b'hey-0' b'hey-1' b'hey-2' ... b'hey-27' b'hey-28' b'hey-29'] at 0x7fe835b54588>
>>> numpy.array(list(t["str"].array()))
array([b'hey-0', b'hey-1', b'hey-2', b'hey-3', b'hey-4', b'hey-5',
b'hey-6', b'hey-7', b'hey-8', b'hey-9', b'hey-10', b'hey-11',
b'hey-12', b'hey-13', b'hey-14', b'hey-15', b'hey-16', b'hey-17',
b'hey-18', b'hey-19', b'hey-20', b'hey-21', b'hey-22', b'hey-23',
b'hey-24', b'hey-25', b'hey-26', b'hey-27', b'hey-28', b'hey-29'],
dtype='|S6')
>>> numpy.array(list(t["str"].array())) == b"hey-0"
array([ True, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False])
循环隐含在遍历 ObjectArray
的 list
构造函数中,将每个元素转换为 bytes
字符串。这个 Python 列表不适合一次数组操作,因此我们构造一个 NumPy 数组,它是(以填充为代价)。
替代方案,可能更好:
在写这篇文章的时候,我想起了uproot的ObjectArray
是用一个笨拙的JaggedArray
实现的,所以上面的转换可以用JaggedArray
的regular
方法来实现,这可能要快得多(没有中间 Python bytes
对象,没有 Python for 循环)。
>>> t["str"].array().regular()
array([b'hey-0', b'hey-1', b'hey-2', b'hey-3', b'hey-4', b'hey-5',
b'hey-6', b'hey-7', b'hey-8', b'hey-9', b'hey-10', b'hey-11',
b'hey-12', b'hey-13', b'hey-14', b'hey-15', b'hey-16', b'hey-17',
b'hey-18', b'hey-19', b'hey-20', b'hey-21', b'hey-22', b'hey-23',
b'hey-24', b'hey-25', b'hey-26', b'hey-27', b'hey-28', b'hey-29'],
dtype=object)
>>> t["str"].array().regular() == b"hey-0"
array([ True, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False])
(上述功能并非有意创建,但它之所以有效,是因为正确的部分以偶然的方式组合而成。)
我有一棵树,其中一个树枝存储着一个字符串。
当我阅读使用 uproot.open()
然后阅读方法 arrays()
时,我得到以下信息:
>>> array_train['backtracked_end_process']
<ObjectArray [b'FastScintillation' b'FastScintillation' b'FastScintillation' ... b'FastScintillation' b'FastScintillation' b'FastScintillation'] at 0x7f48936e6c90>
我想用这个分支来创建面具,通过做一些事情
array_train['backtracked_end_process'] != b'FastScintillation'
但不幸的是,这会产生一个错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-97-a28f3706c5b5> in <module>
----> 1 array_train['backtracked_end_process'] == b'FastScintillation'
~/.local/lib/python3.7/site-packages/numpy/lib/mixins.py in func(self, other)
23 if _disables_array_ufunc(other):
24 return NotImplemented
---> 25 return ufunc(self, other)
26 func.__name__ = '__{}__'.format(name)
27 return func
~/.local/lib/python3.7/site-packages/awkward/array/objects.py in __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
216 contents.append(x)
217
--> 218 result = getattr(ufunc, method)(*contents, **kwargs)
219
220 if self._util_iscomparison(ufunc):
~/.local/lib/python3.7/site-packages/awkward/array/jagged.py in __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
987 data = self._util_toarray(inputs[i], inputs[i].dtype)
988 if starts.shape != data.shape:
--> 989 raise ValueError("cannot broadcast JaggedArray of shape {0} with array of shape {1}".format(starts.shape, data.shape))
990
991 if parents is None:
ValueError: cannot broadcast JaggedArray of shape (24035,) with array of shape ()
有人对如何进行有任何建议吗?能够将其转换为 numpy.chararray
已经可以解决问题,但我不知道该怎么做。
字符串处理是 uproot 中的一个弱点。它使用自定义 ObjectArray
(甚至不是笨拙数组中的 StringArray
),按需生成 bytes
对象。你想要的是一个 class 的字符串数组 ==
重载意味着 "compare each variable-length string, broadcasting a single string to an array if necessary." 不幸的是,无论是根 ObjectArray
的字符串还是 StringArray
class 在笨拙的数组中这样做吧。
诚然,这是通过隐式 Python for 循环实现的方法。
>>> import uproot, numpy
>>> f = uproot.open("http://scikit-hep.org/uproot/examples/sample-6.10.05-zlib.root")
>>> t = f["sample"]
>>> t["str"].array()
<ObjectArray [b'hey-0' b'hey-1' b'hey-2' ... b'hey-27' b'hey-28' b'hey-29'] at 0x7fe835b54588>
>>> numpy.array(list(t["str"].array()))
array([b'hey-0', b'hey-1', b'hey-2', b'hey-3', b'hey-4', b'hey-5',
b'hey-6', b'hey-7', b'hey-8', b'hey-9', b'hey-10', b'hey-11',
b'hey-12', b'hey-13', b'hey-14', b'hey-15', b'hey-16', b'hey-17',
b'hey-18', b'hey-19', b'hey-20', b'hey-21', b'hey-22', b'hey-23',
b'hey-24', b'hey-25', b'hey-26', b'hey-27', b'hey-28', b'hey-29'],
dtype='|S6')
>>> numpy.array(list(t["str"].array())) == b"hey-0"
array([ True, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False])
循环隐含在遍历 ObjectArray
的 list
构造函数中,将每个元素转换为 bytes
字符串。这个 Python 列表不适合一次数组操作,因此我们构造一个 NumPy 数组,它是(以填充为代价)。
替代方案,可能更好:
在写这篇文章的时候,我想起了uproot的ObjectArray
是用一个笨拙的JaggedArray
实现的,所以上面的转换可以用JaggedArray
的regular
方法来实现,这可能要快得多(没有中间 Python bytes
对象,没有 Python for 循环)。
>>> t["str"].array().regular()
array([b'hey-0', b'hey-1', b'hey-2', b'hey-3', b'hey-4', b'hey-5',
b'hey-6', b'hey-7', b'hey-8', b'hey-9', b'hey-10', b'hey-11',
b'hey-12', b'hey-13', b'hey-14', b'hey-15', b'hey-16', b'hey-17',
b'hey-18', b'hey-19', b'hey-20', b'hey-21', b'hey-22', b'hey-23',
b'hey-24', b'hey-25', b'hey-26', b'hey-27', b'hey-28', b'hey-29'],
dtype=object)
>>> t["str"].array().regular() == b"hey-0"
array([ True, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False])
(上述功能并非有意创建,但它之所以有效,是因为正确的部分以偶然的方式组合而成。)