【问题标题】:How to set/get pandas.DataFrame to/from Redis?如何在 Redis 中设置/获取 pandas.DataFrame?
【发布时间】:2016-10-22 23:07:56
【问题描述】:

将 DataFrame 设置为 redis,然后将其取回后,redis 返回一个字符串,我无法找到将这个 str 转换为 DataFrame 的方法。

这两个怎么做才合适?

【问题讨论】:

  • 在放入 Redis 之前使用序列化,从 Redis 读取时使用反序列化。

标签: python pandas dataframe redis


【解决方案1】:

现在是 2021 年,这意味着 df.to_msgpack() 已弃用并且 pyarrow 从 pyarrow 2.0 开始已弃用其自定义序列化功能。 (参见 pyarrow 序列化page987654321@的“任意对象序列化”部分

这就留下了良好且可靠的 msgpack 序列化对象,以便它们可以被推送/存储到 redis 中。

import msgpack
import redis 

# ...Writing to redis (already have data & a redis connection client)
redis_client.set('data_key_name', msgpack.packb(data))

# ...Retrieving from redis
retrieved_data = msgpack.unpackb(redis_client.get('data_key_name'))


【讨论】:

  • 你的例子中的“数据”是什么?
  • 这不起作用假设 data = pandas 数据框,也许澄清你的意思
【解决方案2】:

to_msgpack 在 Pandas 的最新版本中不可用。

import redis
import pandas as pd

# Create a redis client
redisClient = redis.StrictRedis(host='localhost', port=6379, db=0)
# Create un dataframe
dd = {'ID': ['H576','H577','H578','H600', 'H700'],
  'CD': ['AAAAAAA', 'BBBBB', 'CCCCCC','DDDDDD', 'EEEEEEE']}
df = pd.DataFrame(dd)
data = df.to_json()
redisClient.set('dd', data)
# Retrieve the data
blob = redisClient.get('dd')
df_from_redis = pd.read_json(blob)
df_from_redis.head()

output

【讨论】:

    【解决方案3】:
    import pandas as pd
    df = pd.DataFrame([1,2])
    redis.setex('df',100,df.to_json())
    df = redis.get('df')
    df = pd.read_json(df)
    

    【讨论】:

    • 记得提供解释,而不仅仅是代码。帮助读者了解为什么您的代码有效,而不仅仅是做什么,这一点很重要。这在用既定答案回答老问题时尤其重要——在这种情况下,这是近四年前以相当多的票数被接受的答案。除了该建议之外,您的方法还有什么价值?您是否正在使用更快、更清洁或更可靠的新技术?
    【解决方案4】:

    要缓存数据框,请使用它。

    import pyarrow as pa
    
    def cache_df(alias,df):
    
        pool = redis.ConnectionPool(host='host', port='port', db='db')
        cur = redis.Redis(connection_pool=pool)
        context = pa.default_serialization_context()
        df_compressed =  context.serialize(df).to_buffer().to_pybytes()
    
        res = cur.set(alias,df_compressed)
        if res == True:
            print('df cached')
    

    要获取缓存的数据帧,请使用这个。

    def get_cached_df(alias):
    
        pool = redis.ConnectionPool(host='host',port='port', db='db') 
        cur = redis.Redis(connection_pool=pool)
        context = pa.default_serialization_context()
        all_keys = [key.decode("utf-8") for key in cur.keys()]
    
        if alias in all_keys:   
            result = cur.get(alias)
    
            dataframe = pd.DataFrame.from_dict(context.deserialize(result))
    
            return dataframe
    
        return None
    

    【讨论】:

      【解决方案5】:

      我无法使用 msgpack,因为我的数据框中有 Decimal 对象。相反,我像这样将 pickle 和 zlib 组合在一起,假设数据帧 df 和 Redis 的本地实例:

      import pickle
      import redis
      import zlib
      
      EXPIRATION_SECONDS = 600
      
      r = redis.StrictRedis(host='localhost', port=6379, db=0)
      
      # Set
      r.setex("key", EXPIRATION_SECONDS, zlib.compress( pickle.dumps(df)))
      
      # Get
      rehydrated_df = pickle.loads(zlib.decompress(r.get("key")))
      

      没有任何具体的数据框。

      注意事项

      • 使用msgpack 的另一个答案更好——如果它适合你,就使用它
      • 酸洗可能很危险 - 您的 Redis 服务器需要安全,否则您自找麻烦

      【讨论】:

        【解决方案6】:

        设置:

        redisConn.set("key", df.to_msgpack(compress='zlib'))
        

        得到:

        pd.read_msgpack(redisConn.get("key"))
        

        【讨论】:

        猜你喜欢
        • 2021-06-04
        • 1970-01-01
        • 2011-10-26
        • 1970-01-01
        • 2012-06-10
        • 2015-10-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-10
        相关资源
        最近更新 更多