首页 > 解决方案 > 在 if 子句中使用 numpy.float32 值的问题

问题描述

我有一个简单的 GNUradio 测试应用程序,我尝试将 -180...180 范围内的输入转换为 0...360 范围内的输入。我为此编写了 Python 代码和 QA 代码,但似乎无法让 if-else 语句正常工作。

问题似乎是 if 子句只看到测试 src_data 向量的第一个元素,因为我使用 input_elements[0][0]。我尝试使用 input_elements[0],但在这种情况下,我得到了关于将数组与整数进行比较的错误。如何解决这个问题呢?

Python中的块如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy
from gnuradio import gr

class convert_ff(gr.sync_block):
    """
    docstring for block convert_ff
    """
    def __init__(self):
        gr.sync_block.__init__(self,
            name="convert_ff",
            in_sig=[numpy.float32],
            out_sig=[numpy.float32])


    def work(self, input_items, output_items):
    print input_items[:][0]
    out = output_items[0]

    if input_items[0][0] < 0:
        out[:]=360+input_items[0]
        print "negative value processed"
    else:
        out[:]=input_items[0]

    return len(output_items[0])

QA代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from gnuradio import gr, gr_unittest
from gnuradio import blocks
from convert_ff import convert_ff

class qa_convert_ff (gr_unittest.TestCase):

    def setUp (self):
        self.tb = gr.top_block ()

    def tearDown (self):
        self.tb = None

        def test_001_t (self):
        src_data = (20,90,180,280,-20,-90,-190)
        print "This is source data"
        print src_data
        expected_result = (20,90,180,280,340,270,170)
        src=blocks.vector_source_f(src_data)
        convert=convert_ff()
        snk=blocks.vector_sink_f()
        self.tb.connect(src,convert)
        self.tb.connect(convert,snk)
        self.tb.run ()
        # check data
        self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6)


if __name__ == '__main__':
    gr_unittest.run(qa_convert_ff, "qa_convert_ff.xml")

标签: pythonqagnuradio

解决方案


通常要将“if”语句扩展到 numpy.array,最好的解决方案是使用掩码,例如通过将数组与整数(或与另一个相同大小的数组)进行比较而获得的掩码:

mask = input_items[0] < 0

掩码是一个相同维度的布尔数组。然后,您只能使用掩码对数组的选择进行操作:

out[mask] = 360+input_items[mask]

numpy.logical_not() 是获取非掩码的快速方法:

out[numpy.logical_not(mask)] = input_items[numpy.logical_not(mask)]

所以你的工作函数应该是:

def work(self, input_items, output_items):
    print input_items[:][0]
    out = output_items[0]

    mask = input_items[0] < 0
    out[mask] = 360+input_items[mask]
    out[numpy.logical_not(mask)] = input_items[numpy.logical_not(mask)]

    return len(output_items[0])

你可以做得更短,而不是存储面具:

def work(self, input_items, output_items):

    out = input_items[0].copy()
    out[out < 0] += 360.  
    return out

推荐阅读