从具有字符串值和数值的numpy数组中删除NaN

时间:2016-08-04 02:39:10

标签: python arrays numpy

我有一个(M x N) numpy数组,其中包含字符串值,数值和nans。我想删除包含NaN值的行。我试过了:

arr[~np.isnan(arr)]

然而我得到错误:

TypeError: ufunc 'isnan' not supported for the input types, and the inputs 
could not be safely coerced to any supported types according to the casting rule ''save''

我使用的解决方案:

# get column with NaNs, find row index, store in list
nan_idx = []
for v,m in enumerate(arr[:,row]):
    if np.isnan(m):
        nan_idx.append(v)

# separate columns with strings and non strings
numeric_cols = arr[:,:some_idx]
non_numeric_cols = arr[:,other_idx:]

# remove the nans
numeric_cols = numeric_cols[~np.isnan(numeric_cols).any(axis=1)]
non_numeric_cols = np.delete(non_numeric_cols, nan_idx, 0)

2 个答案:

答案 0 :(得分:0)

如果我创建一个对象dtype数组,我会收到你的错误:

In [112]: arr=np.ones((3,2),object)
In [113]: arr
Out[113]: 
array([[1, 1],
       [1, 1],
       [1, 1]], dtype=object)
In [114]: np.isnan(arr)
...
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

dtype是唯一可以混合数字,字符串和np.nan(浮点数)的人。你不能用这个做很多全数组操作。

我无法轻易测试您的解决方案,因为有几个变量未知。

使用更通用的arr,我看不出如何在不迭代行和列的情况下删除行,测试每个值是否为数字,以及数字isnannp.isnan很挑剔,只能在浮动上运行。

正如'可能重复'中提到的,pandas isnull更为通用。

所以基本上有两点:

  • 什么是一个很好的通用测试,可以处理字符串和数字

  • 假设数组是dtype对象,
  • 可以绕过整个迭代。

np.isnan on arrays of dtype "object" 我的解决方案是执行列表推导以循环遍历1d数组。

由此我可以使用:

测试arr的每个元素
In [125]: arr
Out[125]: 
array([['str', 1],
       [nan, 'str'],
       [1, 1]], dtype=object)
In [136]: for row in arr:
     ...:     for col in row:
     ...:         print(np.can_cast(col,float) and np.isnan(col))
False
False
True
False
False
False

答案 1 :(得分:0)

一种解决方案是你可以使用np.sum()对每一行求和。因为nan +任何float = nan,所以你可以得到哪些行包括nan值。

np.sum(arr,axis = 1)
rowsWithoutNaN = [ not(np.isnan(i)) for i in b]
result = np.array( [val for shouldKeep, val in zip(rowsWithoutNaN,arr) if shouldKeep])