最快的将numpy数组存储到redis的方法

我在一个AI项目中使用redis。

这个项目的想法是让多个环境模拟器在大量CPU核心上运行策略。模拟器将经验(状态/动作/奖励元组列表)写入redis服务器(重播缓冲区)。然后训练过程将经验作为数据集读取,以生成新的策略。新策略被部署到模拟器中,之前运行的数据被删除,过程继续进行。

经验的主要部分被捕获在“状态”中。通常表示为一个大的numpy数组,尺寸例如80 x 80。这些模拟器会尽可能快地生成这些数组。

为此,有没有人有关于将大量numpy数组写入redis的最佳/最快/最简单的办法的好主意或经验?这都是在同一台机器上进行的,但后来可能会在云服务器集群上进行。欢迎提供代码样本!


回答:

我不知道这是否是最快的,但你可以尝试这样做…

将Numpy数组存储到Redis的方式如下 – 见函数toRedis()

  • 获取Numpy数组的形状并编码
  • 将Numpy数组作为字节附加到形状
  • 在提供的键下存储编码后的数组

检索Numpy数组的方式如下 – 见函数fromRedis()

  • 从Redis中检索对应于提供的键的编码字符串
  • 从字符串中提取Numpy数组的形状
  • 提取数据并重新填充Numpy数组,调整到原始形状

#!/usr/bin/env python3import structimport redisimport numpy as npdef toRedis(r,a,n):   """将给定的Numpy数组 'a' 存储在Redis下的键 'n' 中"""   h, w = a.shape   shape = struct.pack('>II',h,w)   encoded = shape + a.tobytes()   # 将编码数据存储在Redis中   r.set(n,encoded)   returndef fromRedis(r,n):   """从Redis键 'n' 中检索Numpy数组"""   encoded = r.get(n)   h, w = struct.unpack('>II',encoded[:8])   # 在这里添加切片,否则数组将与原始数组不同   a = np.frombuffer(encoded[8:]).reshape(h,w)   return a# 创建80x80的numpy数组来存储a0 = np.arange(6400,dtype=np.uint16).reshape(80,80) # Redis连接r = redis.Redis(host='localhost', port=6379, db=0)# 将数组a0存储在Redis下的名称'a0array'中toRedis(r,a0,'a0array')# 从Redis中检索a1 = fromRedis(r,'a0array')np.testing.assert_array_equal(a0,a1)

你可以通过编码Numpy数组的dtype和形状来增加更多的灵活性。我没有这样做,因为可能你已经知道你所有的数组都是一种特定的类型,这样做的话代码会变得更大并且更难读,没有任何理由。

现代iMac上的粗略基准测试

80x80的np.uint16类型的Numpy数组   => 写入时间58微秒200x200的np.uint16类型的Numpy数组 => 写入时间88微秒

关键词:Python, Numpy, Redis, 数组, 序列化, 键, incr, 唯一

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注