【问题标题】:How to convert a Numpy 2D array with object dtype to a regular 2D array of floats如何将具有 object dtype 的 Numpy 2D 数组转换为常规的 2D 浮点数组
【发布时间】:2013-10-27 20:23:15
【问题描述】:

作为我正在处理的更广泛程序的一部分,我最终得到了带有字符串、3D 坐标等的对象数组。我知道与结构化数组相比,对象数组可能不是很受欢迎,但我希望在不更改大量代码的情况下解决这个问题。

假设我的数组 obj_array 的每一行(有 N 行)的格式为

Single entry/object of obj_array:  ['NAME',[10.0,20.0,30.0],....] 

现在,我正在尝试加载此对象数组并切片 3D 坐标块。到这里为止,一切都很好,只需询问让我们说 for 。

obj_array[:,[1,2,3]]

但是结果也是一个对象数组,我会遇到问题,因为我想用以下方法形成一个 2D 浮点数组:

size [N,3] of N rows and 3 entries of X,Y,Z coordinates

现在,我正在遍历行并将每一行分配给目标 2D 浮点数组的一行以解决该问题。我想知道 numpy 的数组转换工具是否有更好的方法?我尝试了一些方法,但无法解决。

Centers   = np.zeros([N,3])

for row in range(obj_array.shape[0]):
    Centers[row,:] = obj_array[row,1]

谢谢

【问题讨论】:

  • 您能否展示一个简单的示例代码 - 原始数据是什么样的,您的转换代码是什么样的?它会让别人更容易给你适当的建议。

标签: python arrays object numpy 2d


【解决方案1】:

讨厌的小问题......我一直在玩这个玩具示例:

>>> arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object)
>>> arr
array([['one', [1, 2, 3]],
       ['two', [4, 5, 6]]], dtype=object)

我的第一个猜测是:

>>> np.array(arr[:, 1])
array([[1, 2, 3], [4, 5, 6]], dtype=object)

但这保留了object dtype,所以也许那时:

>>> np.array(arr[:, 1], dtype=np.float)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: setting an array element with a sequence.

您通常可以通过以下方式解决此问题:

>>> np.array(arr[:, 1], dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a readable buffer object

不过这里没有,这有点令人费解。显然,数组中的对象是列表这一事实会引发这种情况,因为用元组替换列表是可行的:

>>> np.array([tuple(j) for j in arr[:, 1]],
...          dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

由于似乎没有任何完全令人满意的解决方案,最简单的可能是:

>>> np.array(list(arr[:, 1]), dtype=np.float)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

虽然这不会很有效,但可能会更好地使用类似的东西:

>>> np.fromiter((tuple(j) for j in arr[:, 1]), dtype=[('', np.float)]*3,
...             count=len(arr)).view(np.float).reshape(-1, 3)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

【讨论】:

  • 我是唯一一个不明白为什么 np.array(arr[:, 1], dtype=np.float) 不起作用的人?
【解决方案2】:

基于 Jaime 的玩具示例,我认为您可以使用 np.vstack() 非常简单地做到这一点:

arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object)
float_arr = np.vstack(arr[:, 1]).astype(np.float)

无论对象数组中的“数字”元素是一维 numpy 数组、列表还是元组,这都会起作用。

【讨论】:

    【解决方案3】:

    这对你的数组 arr 非常有用,可以从一个对象转换为一个浮点数组。号码处理后非常容易。谢谢你最后的帖子!!!!我刚刚修改它以包含任何 DataFrame 大小:

    float_arr = np.vstack(arr[:, :]).astype(np.float)
    

    【讨论】:

    • 这更像是一个评论而不是一个答案。和 ali_m 的回答有关系吗?
    【解决方案4】:

    将对象数组转换为 NumPy 浮点数组会更快: arr=np.array(arr, dtype=[('O', np.float)]).astype(np.float) - 从那里没有循环,索引它就像你通常在 NumPy 数组上做的那样。尽管使用不同的数据类型arr[:, 1]arr[:,2] 等,但您必须分块进行。从 C++ DLL 函数返回的 NumPy 元组对象存在相同的问题 - 17M 元素的转换需要

    【讨论】:

    • 如果有人真的在上面尝试过这个解决方案并对其进行分析,它不会被否决。
    • 我收到“ValueError: setting an array element with a sequence”。这种方法出错.. 示例:aa = [['5236', [1,2,0.3]], ['63734', [6,1.5,0.0]]] bb = np.array(aa, dtype=' object') arr=np.array(bb[:,1], dtype=[('O', np.float)]).astype(np.float)
    【解决方案5】:

    您可能希望使用结构化数组,这样当您需要独立访问名称和值时,您可以轻松地做到这一点。在这个例子中,有两个数据点:

    x = zeros(2, dtype=[('name','S10'), ('value','f4',(3,))])
    x[0][0]='item1'
    x[1][0]='item2'
    y1=x['name']
    y2=x['value']
    

    结果:

    >>> y1
    array(['item1', 'item2'], 
          dtype='|S10')
    >>> y2
    array([[ 0.,  0.,  0.],
           [ 0.,  0.,  0.]], dtype=float32)
    

    查看更多详情:http://docs.scipy.org/doc/numpy/user/basics.rec.html

    【讨论】:

      【解决方案6】:

      当您有不同类型的数据集时,通常会发生此问题,通常是第一列左右的日期。

      我用来做的是将日期列存储在不同的变量中;并将“X 特征矩阵”的其余部分带入 X。例如,我有日期和 X。

      然后我将转换应用于 X 矩阵:

      X = np.array(list(X[:,:]), dtype=np.float)

      希望能提供帮助!

      【讨论】:

        【解决方案7】:

        对于结构化数组使用

        structured_to_unstructured(arr).astype(np.float)
        

        见:https://numpy.org/doc/stable/user/basics.rec.html#numpy.lib.recfunctions.structured_to_unstructured

        【讨论】:

          【解决方案8】:

          np.array(list(arr), dtype=np.float) 可以一次将数组中的所有元素转换为浮点数。

          【讨论】:

            猜你喜欢
            • 2012-06-08
            • 1970-01-01
            • 2013-06-30
            • 2021-12-29
            • 1970-01-01
            • 2019-10-31
            • 2014-08-31
            • 2022-01-17
            相关资源
            最近更新 更多