【问题标题】:Return indices of non-NaN uniques in np.array of dtype=object返回 dtype=object 的 np.array 中非 NaN 唯一值的索引
【发布时间】:2022-01-19 21:56:31
【问题描述】:

如何返回与 np.arraydtype=object 中的唯一值对应的索引列表?

类似于:

arr = np.array(["one", "one", 2, 2])
result = np.unique(arr, return_inverse=True)[1]
print(result)
# [1, 1, 0, 0]

但包含 NaN 值以及在索引期间被忽略的值:

arr = np.array([nan, "one", 2, 2])
result = np.unique(arr, return_inverse=True)[1]
print(result)
# TypeError: '<' not supported between instances of 'float' and 'str'

我已经尝试过以下操作:

arr = np.array([nan, "one", 2, 2])
result = np.unique(arr[~np.isnan(arr)], return_inverse=True)[1]
print(result)
# TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the 

我想从上面的例子中得到什么:

arr = np.array([nan, "one", 2, 2])
result = #...
print(result)
# [nan, 1, 0, 0]

请注意arr 属于dtype=object,因为它包含可变数据类型intstr

提前谢谢你!

【问题讨论】:

  • unique 使用排序,因此无法处理数组的混合对象。
  • @hpaulj 是的,这是有道理的。一种可能的解决方法:如果我用空字符串 "" 替换 NaN 并将数组 dtype 转换为 str 我可以对它们进行排序。但是,我希望始终让 NaN 的索引为 0。空字符串是否确保它们首先被索引?有什么想法吗?
  • 如果你想使用dtype=object,你不妨使用普通的list 并留在 Python 领域
  • 你说得对,更有意义

标签: python list numpy unique nan


【解决方案1】:

在第一个例子中,数组是字符串dtype:

In [293]: arr = np.array(["one", "one", 2, 2])
In [294]: arr
Out[294]: array(['one', 'one', '2', '2'], dtype='<U21')
In [295]: np.unique(arr)
Out[295]: array(['2', 'one'], dtype='<U21')

如果我们指定对象 dtype

In [298]: arr = np.array(["one", "one", 2, 2], object)
In [299]: arr
Out[299]: array(['one', 'one', 2, 2], dtype=object)
In [300]: np.unique(arr)
Traceback (most recent call last):
  ...
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/arraysetops.py", line 333, in _unique1d
    ar.sort()
TypeError: '<' not supported between instances of 'int' and 'str'

注意回溯中的排序

你的nan是什么?

In [306]: arr = np.array([nan, "one", 2, 2])
Traceback (most recent call last):
  File "<ipython-input-306-abe4f4fe7b97>", line 1, in <module>
    arr = np.array([nan, "one", 2, 2])
NameError: name 'nan' is not defined

In [307]: arr = np.array([np.nan, "one", 2, 2])
In [308]: arr
Out[308]: array(['nan', 'one', '2', '2'], dtype='<U32')

nan 是一个浮点数:

In [309]: arr = np.array([np.nan, 3, 2, 2])
In [310]: arr
Out[310]: array([nan,  3.,  2.,  2.])
In [311]: np.unique(arr)
Out[311]: array([ 2.,  3., nan])

unique 在浮点数上可能很棘手,因为如果浮点数并不总是“相等”

np.unique 使用np.lib.arraysetops._unique1d,它对nan 有一些特殊处理(因为nan 不等于任何东西,甚至不等于它自己)。

字符串排序示例

In [321]: np.sort(['one','a','B','','_',' '])
Out[321]: array(['', ' ', 'B', '_', 'a', 'one'], dtype='<U3')

我已经有一段时间没有看字符串排序(ASCII 字符)了,所以不能准确地说出顺序是什么。

【讨论】:

  • 非常感谢。我明白这个问题。 dtype=object 不可排序。是否有一个可排序的dtype 包含除'&lt;U32' 之外的NaN?我已经尝试过'&lt;U32',但很可能我的“NaN”字符串没有得到索引 0。例如当有“。”条目。 “。”由于字符串排序,优先于“NaN”。也许还有一种方法可以掩盖在排序过程中要忽略的 NaN?
  • 根据v8doc.sas.com/sashtml/proc/z1epts.htm“空白ASCII”排名第一。但我不知道用“”替换“NaN”是否是好的编程习惯。我的首要目标是简单地将不同 dtype 的二维数组(或 Pandas df)中的唯一值编码为整数。使用他们的索引是一种方法。现在我想起来pd.factorize() 可能是解决方案。
  • 有一组np.nan... 函数,但它们都依赖于浮动的dtype。 nan 要么被删除,要么被设置为无害的值,因此它可以执行 summean 之类的操作。
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2015-05-09
  • 1970-01-01
  • 2021-10-25
  • 2014-04-03
相关资源
最近更新 更多