【问题标题】:How can I set (dtype=object) numpy array values to Python lists, without numpy interpreting the lists as lists of values?如何将 (dtype=object) numpy 数组值设置为 Python 列表,而不用 numpy 将列表解释为值列表?
【发布时间】:2015-08-06 08:50:07
【问题描述】:

我有一个 dtype=object 数组,其中的值是 Python 列表或 np.nan

我想将 np.nan 的值替换为 [None](不是 None)。

对于纯 Python 列表,我已经可以使用 [ x if (x is not np.nan) else [None] for x in s ] 来完成此操作,并且将数组转换为列表对我的目的来说很好,但出于好奇,我想知道如何使用 numpy 数组来完成此操作。困难在于,当使用索引时,numpy 试图将任何列表解释为值列表,而不是我想要分配的实际值。

例如,如果我想用2 替换值,这很容易(正常的 np、pd 导入;顺便说一句,np.isnan 在这种情况下不起作用,这是选择 float NaN 的一个弱点对于 pandas 中的通用缺失值,所以我使用 pd.isnull,因为无论如何这都是 pandas 内部的问题):

In [53]: s
Out[53]:
array([['asdf', 'asdf'], ['asdf'], nan, ['asdf', 'asdf', 'asdf'],
       ['asdf', 'asdf', 'asdf']], dtype=object)

In [55]: s[pd.isnull(s)] = 2

In [56]: s
Out[56]:
array([['asdf', 'asdf'], ['asdf'], 2, ['asdf', 'asdf', 'asdf'],
       ['asdf', 'asdf', 'asdf']], dtype=object)

然而,试图用 [None] 替换它们而不是用 None 替换它们:

In [58]: s
Out[58]:
array([['asdf', 'asdf'], ['asdf'], nan, ['asdf', 'asdf', 'asdf'],
       ['asdf', 'asdf', 'asdf']], dtype=object)

In [59]: s[pd.isnull(s)] = [None]

In [60]: s
Out[60]:
array([['asdf', 'asdf'], ['asdf'], None, ['asdf', 'asdf', 'asdf'],
       ['asdf', 'asdf', 'asdf']], dtype=object)

显然,这是人们 99% 的时间想要的行为。碰巧这一次,我想将列表分配为一个对象。有什么办法吗?

【问题讨论】:

  • 您总是可以将列表显式包装为一个恰好是列表的对象的标量数组,就像您包装s 本身一样。但这太丑陋了;希望有人有更好的答案……
  • 如果所有元素都是lists,你可以就地改变列表(使用[:] = …),但遗憾的是这在这里没有帮助,因为你显然不能将nan 原地变异为[None]

标签: python numpy


【解决方案1】:

第一个问题是s[…] = [None] 尝试将数组切片替换为一个值的序列None。你真正想要的是用一个值的序列替换切片​​,[None],你可以写成[[None]]

但是,这实际上并不能解决您的问题;这只会让您解决您最初试图提出的问题。

您需要的是明确的数组 1 object 元素恰好是列表[None]。例如:

>>> n = np.array([[None], 0], dtype=object)[:1]
>>> s[pd.isnull(s)] = n

或者,当然:

>>> n = np.empty((1,), dtype=object)
>>> n[0] = [None]
>>> s[pd.isnull(s)] = n

我 90% 确定有一种更简洁易读的方法来创建一个保证具有值 [None] 的单元素数组,并且 80%​​ 确定首先有一种更简单的方法来完成整个事情,所以希望有人能提出更好的答案……但如果没有,这将起作用。

【讨论】:

    【解决方案2】:

    我建议使用numpy.argmin(),因为它返回nan 的位置,然后用[None] 替换它们:

    import numpy as np
    import pandas as pd
    
    def to_none(array_):
        for i in range(array_[pd.isnull(array_)].size):
            array_[np.argmin(array_)] = [None]
        return array_
    
    
    a = np.array([['asdf', 'asdf'], ['asdf'], np.nan, ['asdf', 'asdf', 'asdf'],np.nan,
           ['asdf', 'asdf', 'asdf']], dtype=object)
    a = to_none(a)
    
    print a
    
    >>
    [['asdf', 'asdf'] ['asdf'] [None] ['asdf', 'asdf', 'asdf'] [None]
     ['asdf', 'asdf', 'asdf']]
    
    print a.dtype
    
    >>
    object
    

    【讨论】:

      猜你喜欢
      • 2020-10-05
      • 1970-01-01
      • 2019-03-12
      • 2021-06-09
      • 2017-03-08
      • 2021-08-28
      • 1970-01-01
      • 2023-04-11
      • 2018-04-19
      相关资源
      最近更新 更多