用python为J序列化复数列表

2024-09-27 18:22:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个管道,从Python流式传输数据,并连接到Java应用程序中的流。数据记录是复数矩阵。现在我明白了json.dumps文件()无法处理pythons复杂类型。你知道吗

目前,我已经将复杂值转换为字符串,请将其放入字典中,如下所示:

for entry in range(len(data_array)):
    data_as_string = [str(i) for i in data_array[entry]["DATA"].tolist()]
    send({'data': data_array[entry]["DATA"],
          'coords': data_array[entry]["UVW"].tolist()})

把它送到管道里。但这需要在Java中进行大量且昂贵的自定义反序列化,这会大大增加管道的运行时间。 目前我正在进行反序列化,如下所示:

JSONObject = new JSONOBJECT(string);
try {
            data= jsonObject.getString("data");
            uvw= jsonObject.getString("uvw");
        } catch (JSONException ex) {
            ex.printStackTrace();
        }

然后我做了很多data.replace(string1, string2)来删除序列化添加的一些符号,然后循环遍历矩阵,将每个数字转换成Java复杂类型。 我的Java反序列化代码如下所示:

        data = data.replace("(","");
        data = data.replace(")","");
        data = data.replace("\"","");
        data = data.replace("],[","¦");
        data = data.replace("[","");
        data = data.replace("]","");

        uvw = uvw.replace("[","");
        uvw = uvw.replace("]","");

        String[] frequencyArrays = data.split("¦");
        Complex[][] tempData = new Complex[48][4];
        for(int i=0;i< frequencyArrays.length;i++){
            String[] complexNumbersOfAFrequency = frequencyArrays[i].split(", ");
            for(int j =0;j<complexNumbersOfAFrequency.length;j++){
                boolean realPartNegative = false;
                Complex c;
                if(complexNumbersOfAFrequency[j].startsWith("-")){
                    realPartNegative = true;
                    //Get ridd of the first - sign to be able to split the real & imaginary parts
                    complexNumbersOfAFrequency[j] =complexNumbersOfAFrequency[j].replaceFirst("-","");
                }
                if(complexNumbersOfAFrequency[j].contains("+")){
                    String[] realAndImaginary = complexNumbersOfAFrequency[j].split("\\+");
                    try {
                        double real = Double.parseDouble(realAndImaginary[0]);
                        double imag = Double.parseDouble(realAndImaginary[1].replace("j",""));
                        if(realPartNegative){
                            c = new Complex(-real,imag);
                        } else {
                            c = new Complex(real,imag);
                        }
                    }catch(IndexOutOfBoundsException e) {
                        //System.out.println("Wrongly formatted number, setting it to 0");
                        c = new Complex(0,0);
                    }
                    catch (NumberFormatException e){
                        System.out.println("Wrongly formatted number, setting it to 0");
                        c = new Complex(0,0);
                    }

                } else {
                    String[] realAndImaginary = complexNumbersOfAFrequency[j].split("-");
                    try {
                        double real = Double.parseDouble(realAndImaginary[0]);
                        double imag = Double.parseDouble(realAndImaginary[1].replace("j", "").replace("e", ""));
                        if (realPartNegative) {
                            c = new Complex(-real, -imag);
                        } else {
                            c = new Complex(real, -imag);
                        }
                    }
                        catch(IndexOutOfBoundsException e){
                            System.out.println("Not correctly formatted: ");
                            for(int temp = 0;temp<realAndImaginary.length;temp++){
                                System.out.println(realAndImaginary[temp]);
                            }
                            System.out.println("Setting it to (0,0)");
                            c = new Complex(0,0);
                        }
                        catch (NumberFormatException e){
                            c = new Complex(0,0);
                        }
                    }

                tempData[i][j] = c;
            }

        }

现在我的问题是,是否有办法

1)在Java中反序列化字典,而无需昂贵的字符串操作和循环遍历每个记录或数据的矩阵

2)在python中更好地序列化数据,以便在java中做得更好

如有任何提示,我们将不胜感激。你知道吗

编辑:JSON如下所示

{"data": ["[(1 + 2j), (3 + 4j), ...]","[(5 + 6j), ...]", ..."],

"coords": [1,2,3]}

编辑:对于坐标,我可以很容易地用Java进行反序列化:

uvw = uvw.replace("[","");
uvw = uvw.replace("]","");
String[] coords = uvw.split(",");

然后用Double.parseDouble()coords中转换字符串,但是对于数据字符串来说,这要复杂得多,因为字符串中充满了需要删除的字符,以便获得实际的数字并将它们放在我要转换的Complex[][]中的正确位置


Tags: 字符串newfordata序列化javarealreplace
2条回答

你用的太多了JsonObject.getString,通过使用它来检索非字符串数据。你知道吗

让我们从coords属性开始,因为它是一个更简单的情况。[1,2,3]不是字符串。这是一组数字。因此,应将其检索为数组:

JsonArray coords = jsonObject.getJsonArray("coords");

int count = coords.size();
double[] uvw = new double[count];
for (int i = 0; i < count; i++) {
    uvw[i] = coords.getJsonNumber(i).doubleValue();
}

另一个属性data也是一个数组,但包含字符串元素:

JsonArray data = jsonObject.getJsonArray("data");

int count = data.size();
for (int i = 0; i < count; i++) {
    String complexValuesStr = data.getString(i);
    // ...
}

至于解析出复杂的数字,我不会把这些都做出来字符串.替换电话。相反,您可以使用正则表达式匹配器查找每个复杂值:

Pattern complexNumberPattern = Pattern.compile(
    "\\(\\s*" +         // opening parenthesis
    "(-?[0-9.]+)" +     // group 1: match real part
    "\\s*([-+])\\s*" +  // group 2: match sign
    "([0-9.]+)j" +      // group 3: match imaginary part
    "\\s*\\)");         // closing parenthesis
Matcher matcher = complexNumberPattern.matcher("");

JsonArray data = jsonObject.getJsonArray("data");
int count = data.size();

List<List<Complex>> allFrequencyValues = new ArrayList<>(count);

for (int i = 0; i < count; i++) {

    String complexValuesStr = data.getString(i);

    List<Complex> singleFrequencyValues = new ArrayList<>();

    matcher.reset(complexValuesStr);
    while (matcher.find()) {
        double real = Double.parseDouble(matcher.group(1));
        boolean positive = matcher.group(2).equals("+");
        double imaginary = Double.parseDouble(matcher.group(3));

        Complex value = new Complex(real, positive ? imaginary : -imaginary);
        singleFrequencyValues.add(value);
    }

    allFrequencyValues.add(singleFrequencyValues);
}

不应捕获IndexOutOfBoundsException或NumberFormatException。这表明输入无效。您不应该将无效输入视为零;这意味着发送者犯了错误,您应该确保让他们知道这一点。例外是一个很好的方法。你知道吗

我假设这两个术语总是出现在每个复杂的表达式中。例如,2i将显示为0 + 2j,而不仅仅是2j。像5这样的实数将显示为5 + 0j。如果这不是一个安全的假设,解析就会变得更复杂。你知道吗

因为您关心性能,所以我可以尝试上面的方法;如果使用正则表达式使程序运行太慢,您可以通过单步遍历字符串来查找括号和术语。这将是更多的工作,但可能会提供一个速度增加。你知道吗

如果我理解正确的话,你的矩阵将由复数数组组成,而复数数组又包含实数和虚数。你知道吗

如果是这样,您的数据可能如下所示:

[[{'r':1,'j':2},{'r':3,'j':4}, ...],[{'r':5,'j':6}, ...]]

这意味着您有一个JSON数组,其中包含包含对象的数组。这些对象有两个属性:r定义实数的值和j虚数的值。你知道吗

在Java中解析它应该是直截了当的,也就是说,使用像Jackson或Gson这样的映射器,您只需将它解析成ComplexNumber[][]这样的东西,其中ComplexNumber可以是这样的(简化的):

public class ComplexNumber {
  public double r;
  public double j;
}

当然,可能已经有用于复数的类,所以您可能希望使用这些类。此外,您可能需要手动反序列化(因为目标类不便于映射器,或者您不能/不想使用映射器),但在这种情况下,只需迭代JSONArray元素并从JSONObject中提取rj

相关问题 更多 >

    热门问题