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

How to convert a float array to a single byte string?

我正在尝试向 google 云的 ml-engine 上的模型发送 Json 请求。这需要 json 形式

为此我需要将浮点数组转换为单个 base64 编码字符串

我想也许 google protobuf ByteString would be what I am looking for, but that seems to behave the same way as the byte array

我目前为 "b64" 键创建值的方法会创建一个字节字符串数组,这会导致 google 云错误 (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;
  }

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

万一它有用,我这样做的方式是 Python 是

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

有人可以帮忙吗?谢谢

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; 
   }

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

而且我创建了几个助手 类,您可以将它们放在项目的其他地方(不一定是内部 类)。

主要方法只是提供运行代码的手段

输出如下所示:

编辑我

Original Solution for one b64 item for each float.

{"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;
      }
}

编辑二

Solution for one b64 item with the array of floats encoded as a single string.

{"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;
      }
}