当前位置: 首页 > 面试题库 >

在Redis中存储Numpy数组的最快方法

景英杰
2023-03-14
问题内容

我在AI项目上使用Redis。

这个想法是让多个环境模拟器在许多cpu内核上运行策略。模拟器将体验(状态/操作/奖励元组列表)写入Redis服务器(重播缓冲区)。然后,培训过程将经验作为数据集读取以生成新策略。将新策略部署到模拟器,删除先前运行的数据,然后继续该过程。

大部分经验都记录在“状态”中。通常将其表示为尺寸为80 x 80的大型numpy数组。模拟器会以cpu允许的最快速度生成它们。

为此,是否有人有最好/最快/最简单的方法来编写大量numpy数组来进行redis的构想或经验?这些都在同一台机器上,但是以后可以在一组云服务器上。代码示例欢迎!


问题答案:

我不知道它是否最快,但是您可以尝试类似的方法…

将一个Numpy数组存储到Redis就像这样-see function toRedis()

  • 获得Numpy数组的形状并进行编码
  • 将Numpy数组作为字节附加到形状
  • 将编码的数组存储在提供的密钥下

检索一个Numpy数组是这样的-see function fromRedis()

  • 从Redis检索与提供的密钥相对应的编码字符串
  • 从字符串中提取Numpy数组的形状
  • 提取数据并重新填充Numpy数组,重塑为原始形状
#!/usr/bin/env python3

import struct
import redis
import numpy as np

def toRedis(r,a,n):
   """Store given Numpy array 'a' in Redis under key 'n'"""
   h, w = a.shape
   shape = struct.pack('>II',h,w)
   encoded = shape + a.tobytes()

   # Store encoded data in Redis
   r.set(n,encoded)
   return

def fromRedis(r,n):
   """Retrieve Numpy array from Redis key 'n'"""
   encoded = r.get(n)
   h, w = struct.unpack('>II',encoded[:8])
   a = np.frombuffer(encoded, dtype=np.uint16, offset=8).reshape(h,w)
   return a

# Create 80x80 numpy array to store
a0 = np.arange(6400,dtype=np.uint16).reshape(80,80)

# Redis connection
r = redis.Redis(host='localhost', port=6379, db=0)

# Store array a0 in Redis under name 'a0array'
toRedis(r,a0,'a0array')

# Retrieve from Redis
a1 = fromRedis(r,'a0array')

np.testing.assert_array_equal(a0,a1)

您可以通过dtype对Numpy数组的以及形状进行编码来增加灵活性。我之所以没有这样做,是因为您可能已经知道所有数组都属于一种特定类型,然后代码会变得更大且更难于无故读取。

在现代iMac上的大致基准

80x80 Numpy array of np.uint16   => 58 microseconds to write
200x200 Numpy array of np.uint16 => 88 microseconds to write

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



 类似资料:
  • 问题内容: 要求: 我需要从数据中任意增加一个数组。 我可以猜测大小(大约100-200),但不能保证每次都适合该数组 一旦增长到最终大小,我就需要对其进行数值计算,因此我更希望最终使用二维numpy数组。 速度至关重要。例如,对于300个文件之一,update()方法被称为4500万次(大约需要150秒),而finalize()方法被称为500k次(总共需要106s)……总共需要250s或者。

  • 问题内容: 我有一个脚本,生成 带有和形状为的二维s 。现在,我正在使用阵列并执行IO操作。但是,这些功能对于每个阵列都需要花费几秒钟。是否有更快的方法来保存和加载整个数组(即,无需假设其内容并减少它们)?我愿意在保存之前将s转换为另一种类型,只要准确保留数据即可。 问题答案: 对于真正的大型阵列,我听说过几种解决方案,它们大多是对I / O懒惰: NumPy.memmap,将大数组映射为二进制形

  • 问题内容: 我正在使用Redis来存储一些信息并检测该信息随时间的变化(例如,考虑用户和位置)。使用更长或更短的键名的值是什么?使用更长的键会更清楚,但是使用更长的键名是否会在内存或性能上付出很多成本? 以下是示例: 要么 问题答案: 这完全取决于您将如何使用它。如果每个字节都很重要,例如,当您必须为传输到云服务的每个kB支付费用时,您可以计算成本。数学很简单;一个字节是“在线”上的一个字节。在r

  • 问题内容: 我知道我可以像下面这样: 但是,由于它做了完整的排序,所以它非常慢。 我想知道numpy是否提供一些可以快速完成的方法。 问题答案: 该模块具有一种快速的局部排序方法,可直接与Numpy数组配合使用:。 请注意,返回的是已排序的实际值,如果要使用已排序的值的索引(返回值),则应使用。 我已经进行了基准测试: 其中是一个随机的1,000,000个元素的数组。 时间安排如下: :每个循环2

  • 问题内容: 我有一个要存储在Redis中的对象数组。我可以分解数组部分,并将它们存储为对象,但是我不知道如何获得类似 然后根据名称搜索数据库,并获取返回的密钥。我需要这样的东西。但几乎无法做到正确。 首先是使这一部分正确。 其次是以某种方式从值中获取密钥,即 我觉得很难。或者,我可以将其直接存储为对象数组并使用简单的for循环。 请建议哪种路线最适合某些实现? 问题答案: 我发现工作是将密钥存储为

  • 问题内容: 我对Redis还是很陌生,希望看看是否有可能。想象一下我正在接收这样的数据: 并为另一个帐户接收此数据: 我想以类似的格式将这些数据保留在Redis中: 对于xyz: 所以问题是我应该使用哪种数据类型来存储此Redis? 问题答案: 如果您的目标是检查是否用作该帐户的解决方案,则解决方案应类似于: 样本数据 执行此操作( 使用redis集 ): 然后,您可以通过以下命令检查是否用作该帐