【问题标题】:Ndarray of lists with mix of floats and integers?混合了浮点数和整数的列表的Ndarray?
【发布时间】:2020-09-20 07:43:53
【问题描述】:

我有一个列表数组(更正:N 维数组)

s_cluster_data
Out[410]: 
array([[ 0.9607611 ,  0.19538569,  0.        ],
       [ 1.03990463,  0.22274072,  0.        ],
       [ 1.09430461,  0.22603228,  0.        ],
       ...,
       [ 1.10802461, -0.54190659,  2.        ],
       [ 0.9288097 , -0.49195368,  2.        ],
       [ 0.81606986, -0.47141286,  2.        ]])

我想将第三列设为整数。我试图这样分配dtype

dtype=[('A','f8'),('B','f8'),('C','i4')]

s_cluster_data = np.array(s_cluster_data, dtype=dtype)
s_cluster_data

Out[414]: 
array([[( 0.9607611 ,  0.9607611 , 0), ( 0.19538569,  0.19538569, 0),
        ( 0.        ,  0.        , 0)],
       [( 1.03990463,  1.03990463, 1), ( 0.22274072,  0.22274072, 0),
        ( 0.        ,  0.        , 0)],
       [( 1.09430461,  1.09430461, 1), ( 0.22603228,  0.22603228, 0),
        ( 0.        ,  0.        , 0)],
       ...,
       dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<i4')])

它创建了一个元组列表数组(corr: array with dtype),列表中的每个索引成为一个单独的元组。

我也尝试过拆开数组,将其作为元组数组读入,然后返回原始状态。

list_cluster = s_cluster_data.tolist() # py list
tuple_cluster = [tuple(l) for l in list_cluster] # list of tuples

dtype=[('A','f8'),('B','f8'),('C','i4')]
sd_cluster_data = np.array(tuple_cluster, dtype=dtype) # array of tuples with dtype
sd_cluster_data

Out:   ...,
       (1.0020371 , -0.56034073, 2), (1.18264038, -0.55773913, 2),
       (1.00550194, -0.55359672, 2), (1.10802461, -0.54190659, 2),
       (0.9288097 , -0.49195368, 2), (0.81606986, -0.47141286, 2)],
      dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<i4')])

所以理想情况下,上面的输出是我希望看到的,但使用的是列表数组,而不是元组数组。 我试图将数组分开并将其合并为列表

x_val_arr = np.array([x[0] for x in sd_cluster_data])
y_val_arr = np.array([x[1] for x in sd_cluster_data])
cluster_id_arr = np.array([x[2] for x in sd_cluster_data])

coordinates_arr = np.stack((x_val_arr,y_val_arr,cluster_id_arr),axis=1)

但我再次在第三列中得到浮动

coordinates_arr
Out[416]: 
array([[ 0.9607611 ,  0.19538569,  0.        ],
       [ 1.03990463,  0.22274072,  0.        ],
       [ 1.09430461,  0.22603228,  0.        ],
       ...,
       [ 1.10802461, -0.54190659,  2.        ],
       [ 0.9288097 , -0.49195368,  2.        ],
       [ 0.81606986, -0.47141286,  2.        ]])

因此,由于我缺乏领域知识,这可能是一个问题,但是如果 ndarrays 由列表而不是元组组成,它是否不支持混合数据类型?

【问题讨论】:

  • “我有一个列表数组”不,你这样做不是。即使你这样做了,你不应该。你有一个二维数组。 “它创建了一个元组列表数组”不,它没有。那是一个具有结构化 dtype 的数组。所有数组都支持单一数据类型(不过,该数据类型可能是结构)。 Numpy 数组本质上是围绕原始的、固定大小的数组的面向对象的包装器。你可以使用dtype=object,但这几乎没有意义,因为它本质上变成了一个效率较低的list
  • 感谢您更正我的术语,所以数组不能支持多种数据类型,但一种数据类型可以有多个元素。

标签: python numpy


【解决方案1】:
In [87]: import numpy.lib.recfunctions as rf                                    
In [88]: arr = np.array([[ 0.9607611 ,  0.19538569,  0.        ], 
    ...:        [ 1.03990463,  0.22274072,  0.        ], 
    ...:        [ 1.09430461,  0.22603228,  0.        ], 
    ...:        [ 1.10802461, -0.54190659,  2.        ], 
    ...:        [ 0.9288097 , -0.49195368,  2.        ], 
    ...:        [ 0.81606986, -0.47141286,  2.        ]])         
In [89]: arr                                                                    
Out[89]: 
array([[ 0.9607611 ,  0.19538569,  0.        ],
       [ 1.03990463,  0.22274072,  0.        ],
       [ 1.09430461,  0.22603228,  0.        ],
       [ 1.10802461, -0.54190659,  2.        ],
       [ 0.9288097 , -0.49195368,  2.        ],
       [ 0.81606986, -0.47141286,  2.        ]])

有多种方法可以像这样从二维数组构造结构化数组。最近的版本提供了一个方便的unstructured_to_structured 函数:

In [90]: dt = np.dtype([('A','f8'),('B','f8'),('C','i4')])     
In [92]: rf.unstructured_to_structured(arr, dt)                                 
Out[92]: 
array([(0.9607611 ,  0.19538569, 0), (1.03990463,  0.22274072, 0),
       (1.09430461,  0.22603228, 0), (1.10802461, -0.54190659, 2),
       (0.9288097 , -0.49195368, 2), (0.81606986, -0.47141286, 2)],
      dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<i4')])

arr 的每一行都变成了结构化记录,显示为一个元组。

一种功能等效的方法是创建一个“空白”数组,并按名称分配字段值:

In [93]: res = np.zeros(arr.shape[0], dt)                                       
In [94]: res                                                                    
Out[94]: 
array([(0., 0., 0), (0., 0., 0), (0., 0., 0), (0., 0., 0), (0., 0., 0),
       (0., 0., 0)], dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<i4')])
In [95]: res['A'] = arr[:,0]                                                    
In [96]: res['B'] = arr[:,1]                                                    
In [97]: res['C'] = arr[:,2]                                                    
In [98]: res                                                                    
Out[98]: 
array([(0.9607611 ,  0.19538569, 0), (1.03990463,  0.22274072, 0),
       (1.09430461,  0.22603228, 0), (1.10802461, -0.54190659, 2),
       (0.9288097 , -0.49195368, 2), (0.81606986, -0.47141286, 2)],
      dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<i4')])

为了强调这一点,我们还可以从元组列表中创建结构化数组:

In [104]: np.array([tuple(row) for row in arr.tolist()], dt)                    
Out[104]: 
array([(0.9607611 ,  0.19538569, 0), (1.03990463,  0.22274072, 0),
       (1.09430461,  0.22603228, 0), (1.10802461, -0.54190659, 2),
       (0.9288097 , -0.49195368, 2), (0.81606986, -0.47141286, 2)],
      dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<i4')])

【讨论】:

  • 这是一个非常酷的功能,比我做的要干净得多。只是为了确认, dtype 只能应用于元组对吗?所以我看不到类似:Out: array([[0.9288097 , -0.49195368, 2], [.81606986, -0.47141286, 2)]] dtype=[('A', '&lt;f8'), ('B', '&lt;f8'), ('C', '&lt;i4')])
  • 是的,开发人员选择使用元组作为定义record 的方式,用于输入和显示。这有助于将dtype 分组与常规维度(显示为嵌套列表)区分开来。
【解决方案2】:

问题可能在于您将数据传递给np.array 的方式。数组的行应该是元组。

 a = np.array([( 0.9607611 ,  0.19538569,  0.        )], dtype='f8, f8, i4')

将创建一个数组

array([(0.9607611, 0.19538569, 0)],
      dtype=[('f0', '<f8'), ('f1', '<f8'), ('f2', '<i4')])

【讨论】:

  • 我明白了,这确实可以解决问题。不幸的是,原始数组是由sklearn.datasets 中的make_blobs 生成的,它将它生成为两个列表数组,而不是元组,然后我将它们连接起来,但我可以检查是否有办法使用它。
猜你喜欢
  • 2021-09-24
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多