在对象数据类型的重新排列中删除具有nan值的行

时间:2017-01-25 05:15:57

标签: numpy nan recarray

以下是我的意见:

data = np.array ( [ ( 'a2', 'b1', 'c1' ), ( 'a1', 'b1', 'c1' ), ( 'a2', np.NaN, 'c2' ) ], dtype = [ ( 'A', 'O' ), ( 'B', 'O' ), ( 'C', 'O' ) ] ) . view ( np.recarray)

我想将此作为输出:

rec.array ( [ ( 'a2', 'b1', 'c1' ), ( 'a1', 'b1', 'c1' ) ], dtype = [ ( 'A', 'O'), ( 'B', 'O' ), ( 'C', 'O' )  ] )

我试过了:

data [ data [ 'B' ] ! = np.NaN ] . view ( np.recarray )

但它不起作用。

data [ data [ 'A' ] ! = 'a2' ] . view ( np.recarray ) 

给出所需的输出。

为什么此方法不适用于np.NaN?如何在对象数据类型的重新排列中删除包含np.NaN值的行?此外,~np.isnan()不适用于对象数据类型。

1 个答案:

答案 0 :(得分:0)

定义一个应用String key = databaseReference.push().getKey(); // gets a unique ID databaseReference .child(firebaseUser.getUid()) .child("question"+key) .setValue(nqd); 的函数,但不会阻塞字符串):

np.isnan

并使用def foo(item): try: return np.isnan(item) except TypeError: return False 创建一个函数,将其应用于数组元素,并返回一个布尔数组:

vectorize

使用f=np.vectorize(foo, otypes=[bool])

data

==============

在所有字段上执行此测试删除的最简单方法是迭代字段名称:

In [240]: data = np.array ( [ ( 'a2', 'b1', 'c1' ), ( 'a1', 'b1', 'c1' ), ( 'a2' , np.NaN, 'c2' ) ], dtype = [ ( 'A', 'O' ), ( 'B', 'O' ), ( 'C', 'O' ) ] )
In [241]: data
Out[241]: 
array([('a2', 'b1', 'c1'), ('a1', 'b1', 'c1'), ('a2', nan, 'c2')], 
      dtype=[('A', 'O'), ('B', 'O'), ('C', 'O')])
In [242]: data['B']
Out[242]: array(['b1', 'b1', nan], dtype=object)

In [243]: f(data['B'])
Out[243]: array([False, False,  True], dtype=bool)

In [244]: data[~f(data['B'])]
Out[244]: 
array([('a2', 'b1', 'c1'), ('a1', 'b1', 'c1')], 
      dtype=[('A', 'O'), ('B', 'O'), ('C', 'O')])

In [429]: data # expanded with more nan Out[429]: array([('a2', 'b1', 'c1'), ('a1', 'b1', 'c1'), ('a2', nan, 'c2'), ('a2', 'b1', nan), (nan, 'b1', 'c1')], dtype=[('A', 'O'), ('B', 'O'), ('C', 'O')]) 函数应用于每个字段并收集到数组中:

f

使用In [441]: np.array([f(data[name]) for name in data.dtype.names]) Out[441]: array([[False, False, False, False, True], [False, False, True, False, False], [False, False, False, True, False]], dtype=bool) 获取任何项目为True的列:

any

(在Ipython中In [442]: np.any(_, axis=0) Out[442]: array([False, False, True, True, True], dtype=bool) In [443]: data[_] # the ones with nan Out[443]: array([('a2', nan, 'c2'), ('a2', 'b1', nan), (nan, 'b1', 'c1')], dtype=[('A', 'O'), ('B', 'O'), ('C', 'O')]) In [444]: data[~__] # the ones without Out[444]: array([('a2', 'b1', 'c1'), ('a1', 'b1', 'c1')], dtype=[('A', 'O'), ('B', 'O'), ('C', 'O')]) _包含以前__行中显示的结果。)

Out将数组转换为元组列表(结构化数组的记录显示为元组):

tolist

In [448]: data.tolist() Out[448]: [('a2', 'b1', 'c1'), ('a1', 'b1', 'c1'), ('a2', nan, 'c2'), ('a2', 'b1', nan), (nan, 'b1', 'c1')] 作为f函数可以将vectorized应用于每个元素(显然它foo}

np.array(data.tolist(), dtype=object)

我之前从未尝试过这种In [449]: f(data.tolist()) Out[449]: array([[False, False, False], [False, False, False], [False, True, False], [False, False, True], [ True, False, False]], dtype=bool) In [450]: np.any(_, axis=1) Out[450]: array([False, False, True, True, True], dtype=bool) tolist的组合。向量化函数迭代它们的输入,因此它们没有提供比显式迭代更多的速度优势,但对于这样的任务,它确实简化了编码。

另一种可能性是定义vectorize以跨记录的字段进行操作。事实上,当我尝试将foo应用于单个记录时,我发现了tolist技巧:

f