【问题标题】:Compare two ndarrays with different dimensions比较两个不同维度的ndarray
【发布时间】:2018-02-28 19:28:32
【问题描述】:

我有两个 ndarray。第一个 ndarray 在一列中有字符串,在另一列中有浮点值。第二个 ndarray 仅包含一列字符串值。

例如:

   Array1                Array2
"abc"     1.000          "abc"
"fsfds"  -5.000          "qw"
"svs"     2.094          "svs"
"dfdsge"  3.348          "dd"  

我的问题是,如何比较 Array1 和 Array2 中的匹配字符串值,然后从 Array1 返回相应的浮点值?

我尝试 set(Array1) & set(Array2) 来查找唯一元素,但不知道如何提取浮点值。 numpy里面有函数吗?

谢谢。

【问题讨论】:

  • 这些数组的 dtype 和 shape 是什么?根据其构造方式,Array1 可以是 1d 的 2 个字段,或者是 2d 的字符串 dtype。
  • @hpaulj 对于两个 ndarray 我已将对象分配为 dtype
  • 那么Array1[:,0] 应该是可以与Array2 进行比较的一维数组。我不确定让他们object dtype 会如何影响比较。我们会玩弄它。
  • 将 dtype 分配为 Array1 的 str 和 int 是否更好?

标签: python numpy multidimensional-array


【解决方案1】:

我认为列表推导可以在这里解决问题:

Output=[i[1] for i in Array1 if i[0] in Array2]

【讨论】:

  • 它只是返回了字符串的首字母但是谢谢
  • 对不起,我的错误。我正在编辑它以使其正常工作
【解决方案2】:

将示例转换为数组的最简单方法是将其复制粘贴为多行字符串,然后使用genfromtxt 对其进行解析:

In [344]: txt=b'''"abc"     1.000          "abc"
     ...: "fsfds"  -5.000          "qw"
     ...: "svs"     2.094          "svs"
     ...: "dfdsge"  3.348          "dd"  '''

In [346]: np.genfromtxt(txt.splitlines(),dtype=None)
Out[346]: 
array([(b'"abc"',  1.   , b'"abc"'), (b'"fsfds"', -5.   , b'"qw"'),
       (b'"svs"',  2.094, b'"svs"'), (b'"dfdsge"',  3.348, b'"dd"')],
      dtype=[('f0', 'S8'), ('f1', '<f8'), ('f2', 'S5')])

使用dtype=None 它推导出列dtype,并创建一个结构化数组。我可以把它分成 2 个数组,一个有 2 个字段,另一个有 1 个。这些都是 1d。

In [347]: arr1, arr2 = _[['f0','f1']], _['f2']
In [348]: arr1
Out[348]: 
array([(b'"abc"',  1.   ), (b'"fsfds"', -5.   ), (b'"svs"',  2.094),
       (b'"dfdsge"',  3.348)],
      dtype=[('f0', 'S8'), ('f1', '<f8')])
In [349]: arr2
Out[349]: 
array([b'"abc"', b'"qw"', b'"svs"', b'"dd"'],
      dtype='|S5')

您不太清楚要如何比较文本列。使用这些数据看起来合理的一个简单方法就是逐个元素,简单的==

In [350]: arr1['f0']==arr2
Out[350]: array([ True, False,  True, False], dtype=bool)

使用这个布尔掩码,我可以轻松选择arr1 的元素:

In [351]: arr1[_]
Out[351]: 
array([(b'"abc"',  1.   ), (b'"svs"',  2.094)],
      dtype=[('f0', 'S8'), ('f1', '<f8')])

让我们看看我能不能把它们变成对象数组。


In [372]: array1 = np.array(arr1.tolist(),dtype=object)
In [373]: array2 = np.array(arr2.tolist(),dtype=object)
In [374]: array1
Out[374]: 
array([[b'"abc"', 1.0],
       [b'"fsfds"', -5.0],
       [b'"svs"', 2.094],
       [b'"dfdsge"', 3.348]], dtype=object)
In [375]: array2
Out[375]: array([b'"abc"', b'"qw"', b'"svs"', b'"dd"'], dtype=object)

我们可以得到相同的面具:

In [376]: array1[:,0]==array2
Out[376]: array([ True, False,  True, False], dtype=bool)
In [377]: array1[_,:]
Out[377]: 
array([[b'"abc"', 1.0],
       [b'"svs"', 2.094]], dtype=object)

另一种获取面具的方法:

In [378]: np.in1d(array2,array1[:,0])
Out[378]: array([ True, False,  True, False], dtype=bool)

在这种情况下,它会产生同样的结果

实际上要得到array2中的array1的行(任意顺序),我们需要切换顺序:

In [389]: np.in1d(array1[:,0],array2[[1,0,3,2]])
Out[389]: array([ True, False,  True, False], dtype=bool)

查看in1d 和相关数组set 函数了解更多想法和细节。

在任何情况下,使用field 或列选择来获取可以与另一个数组中的字符串进行比较的一维字符串数组。

【讨论】:

    【解决方案3】:

    您可以使用数组比较作为第一个维度的索引来选择所需的行。我不确定你是如何拥有一个同时包含字符串和浮点数的 ndarray,但这里有一个示例,我们将它设置为第一行和最后一行在第一列中具有相同的值。

    import numpy as np
    
    array_1 = np.random.randn(4, 2)
    array_2 = np.random.randn(4)
    array_2[3] = array_1[3, 0]
    array_2[0] = array_1[0, 0]
    
    print(array_1, array_2)
    print(array_1[array_1[:, 0] == array_2, 1])
    

    这给了

    [[ 0.76170733 -1.40708366]
     [-1.42535617 -1.03982291]
     [ 0.67999753 -0.92733875]
     [ 0.96474552 -1.95639871]]
    [ 0.76170733  0.95046454  0.1548689   0.96474552]
    [-1.40708366 -1.95639871]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 2013-04-02
      • 2021-02-25
      • 2016-08-03
      相关资源
      最近更新 更多