如何将float数组转换为单字节字符串?

问题描述 投票:1回答:2

我试图将一个Json请求发送到google cloud的ml-engine上的模型。这需要表格中的json

我需要将float数组转换为单个base64编码的字符串。

我想也许google protobuf ByteString将是我正在寻找的,但这似乎与字节数组(stackoverflow question on the difference between the two)的行为相同。

我目前为“b64”键创建值的方法会创建一个字节字符串数组,这会导致谷歌云错误(see other question)

  public static String[] convertToBase64Bytes(float[] audio) {
    String[] data = new String[audio.length];
    for (int i = 0; i < audio.length; i++) {
      float amplitude = audio[i];
      byte[] byteArray = ByteBuffer.allocate(4).putFloat(amplitude).array();
      data[i] = Base64.encodeToString(byteArray, Base64.DEFAULT);
    }
    return data;
  }

我一直无法找到如何将整个float数组转换为单个base64字节字符串,然后ml-engine可以转换回原始数组。

如果它有用,我这样做的方式就是Python

bytes_string = audio_array.tostring() #audio_array is a numpy array
encoded = base64.b64encode(bytes_string)

有人能帮忙吗?谢谢。

java android arrays google-cloud-platform google-cloud-ml
2个回答
0
投票

对于这个解决方案,我使用Gson()(you can the jar or the maven dependencies from here) to生成最终字符串,如您的示例所示。

我创建了一些辅助类,你可以把它放在项目的其他地方(不一定是内部类)。

主要方法是提供运行代码的方法。

输出如下所示:

编辑我

每个浮子的一个b64项目的原始解决方案。

{"instances":[{"b64":"QUczMw=="},{"b64":"QgpmZg=="},{"b64":"wgHS8g=="},{"b64":"QU+uFA=="}]}

代码:

public class FloatEncoder {

    public static void main(String args[]) {
        FloatEncoder encoder = new FloatEncoder();

        float [] floats = new float[] {12.45f, 34.6f, -32.456f, 12.98f};
        String encodedJson = encoder.encode(floats);
        System.out.println(encodedJson);
    }

    private String encode(float[] floats) {
        String rtn;
        DataHolder holder = new DataHolder();


        String [] audios = convertToBase64Bytes(floats);

        for(String audio : audios) {
            B64 b64 = new B64();
            b64.b64 = audio;
            holder.instances.add(b64);
        }

        Gson gson = new GsonBuilder().disableHtmlEscaping().create();
        rtn = gson.toJson(holder);

        return rtn;
    }

      public static String[] convertToBase64Bytes(float[] audio) {
        String[] data = new String[audio.length];
        for (int i = 0; i < audio.length; i++) {
          float amplitude = audio[i];
          byte[] byteArray = ByteBuffer.allocate(4).putFloat(amplitude).array();
          data[i] = Base64.getEncoder().encodeToString(byteArray);
        }
        return data;
      }

      public static class DataHolder{
          public ArrayList<B64> instances = new ArrayList<>();
      }

      public static class B64{
          public String b64;
      }
}

编辑二

一个b64项的解决方案,浮点数组编码为单个字符串。

{"instances":[{"b64":"QUczM0IKZmbCAdLyQU+uFA=="}]}

字符串是字节数组的Base64编码,其中前4个字节是第一个浮点数,第二个4是第二个浮点数,依此类推。

public class FloatEncoder {

    public static void main(String args[]) {
        FloatEncoder encoder = new FloatEncoder();

        float [] floats = new float[] {12.45f, 34.6f, -32.456f, 12.98f};
        String encodedJson = encoder.encode(floats);
        System.out.println(encodedJson);
    }

    private String encode(float[] floats) {
        String rtn;
        DataHolder holder = new DataHolder();


        String audios = convertToBase64Bytes(floats);
        B64 b64 = new B64();
        b64.b64 = audios;
        holder.instances.add(b64);

        Gson gson = new GsonBuilder().disableHtmlEscaping().create();
        rtn = gson.toJson(holder);

        return rtn;
    }

      public static String convertToBase64Bytes(float[] audio) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(4 * audio.length);
        for (int i = 0; i < audio.length; i++) {
          float amplitude = audio[i];  
          byteBuffer.putFloat(amplitude);
        }
        byte[] data = byteBuffer.array();
        String rtn = Base64.getEncoder().encodeToString(data);
        return rtn;
      }

      public static class DataHolder{
          public ArrayList<B64> instances = new ArrayList<>();
      }

      public static class B64{
          public String b64;
      }
}

2
投票
public static String convertToBase64Bytes(float[] audio) { 
     ByteBuffer buff = ByteBuffer.allocate(4 * audio.length);
     for (int i = 0; i < audio.length; i++) {
       float amplitude = audio[i]; 
       buff.putFloat(amplitude);
     }
     String data = Base64.getEncoder().encodeToString(buff.array(), Base64.DEFAULT);
     return data; 
   }
© www.soinside.com 2019 - 2024. All rights reserved.