Как установить / получить фреймы данных Pandas в Redis с помощью pyarrow
С помощью
dd = {'ID': ['H576','H577','H578','H600', 'H700'],
'CD': ['AAAAAAA', 'BBBBB', 'CCCCCC','DDDDDD', 'EEEEEEE']}
df = pd.DataFrame(dd)
До Pandas 0.25 это работало ниже.
set: redisConn.set("key", df.to_msgpack(compress='zlib'))
get: pd.read_msgpack(redisConn.get("key"))
Теперь есть устаревшие предупреждения.
FutureWarning: to_msgpack is deprecated and will be removed in a future version.
It is recommended to use pyarrow for on-the-wire transmission of pandas objects.
The read_msgpack is deprecated and will be removed in a future version.
It is recommended to use pyarrow for on-the-wire transmission of pandas objects.
Как работает пиарроу? И как мне получить объекты Pyarrow в Redis и обратно.
ссылка: Как установить / получить pandas.DataFrame в / из Redis?
6 ответов
Решение
Вот полный пример использования pyarrow для сериализации фрейма данных pandas для хранения в redis
apt-get install python3 python3-pip redis-server
pip3 install pandas pyarrow redis
а затем в питоне
import pandas as pd
import pyarrow as pa
import redis
df=pd.DataFrame({'A':[1,2,3]})
r = redis.Redis(host='localhost', port=6379, db=0)
context = pa.default_serialization_context()
r.set("key", context.serialize(df).to_buffer().to_pybytes())
context.deserialize(r.get("key"))
A
0 1
1 2
2 3
Я только что отправил PR 28494 в pandas, чтобы включить этот пример pyarrow в документы.
Справочные документы:
Вот как я это делаю, поскольку default_serialization_context устарел, а все немного проще:
import pyarrow as pa
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
def storeInRedis(alias, df):
df_compressed = pa.serialize(df).to_buffer().to_pybytes()
res = r.set(alias,df_compressed)
if res == True:
print(f'{alias} cached')
def loadFromRedis(alias):
data = r.get(alias)
try:
return pa.deserialize(data)
except:
print("No data")
storeInRedis('locations', locdf)
loadFromRedis('locations')
Если вы хотите сжать данные в Redis, вы можете использовать встроенную поддержку parquet и gzip.
def openRedisCon():
pool = redis.ConnectionPool(host=REDIS_HOST, port=REDIS_PORT, db=0)
r = redis.Redis(connection_pool=pool)
return r
def storeDFInRedis(alias, df):
"""Store the dataframe object in Redis
"""
buffer = io.BytesIO()
df.to_parquet(buffer, compression='gzip')
buffer.seek(0) # re-set the pointer to the beginning after reading
r = openRedisCon()
res = r.set(alias,buffer.read())
def loadDFFromRedis(alias, useStale: bool = False):
"""Load the named key from Redis into a DataFrame and return the DF object
"""
r = openRedisCon()
try:
buffer = io.BytesIO(r.get(alias))
buffer.seek(0)
df = pd.read_parquet(buffer)
return df
except:
return None
Pickle и zlib могут быть альтернативой pyarrow:
import pandas as pd
import redis
import zlib
import pickle
df=pd.DataFrame({'A':[1,2,3]})
r = redis.Redis(host='localhost', port=6379, db=0)
r.set("key", zlib.compress( pickle.dumps(df)))
df=pickle.loads(zlib.decompress(r.get("key")))
import pandas as pd
import redis
import pickle
r = redis.Redis(host='localhost', port=6379, db=0)
data = {
"calories": ["v1", 'v2', 'v3'],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data, index=["day1", "day2", "day3"])
r.set("key", pickle.dumps(df))
print(pickle.loads(r.get("key")))
альтернативно вы можете использовать Direct-Redis
import pandas as pd
from direct_redis import DirectRedis
r = DirectRedis(host='localhost', port=6379)
>>> df = pd.DataFrame([[1,2,3,'235', '@$$#@'],
['a', 'b', 'c', 'd', 'e']])
>>> print(df)
0 1 2 3 4
0 1 2 3 235 @$$#@
1 a b c d e
>>> r.set('df', df)
>>> r.get('df')
0 1 2 3 4
0 1 2 3 235 @$$#@
1 a b c d e
>>> type(r.get('df'))
<class 'pandas.core.frame.DataFrame'>
import pandas as pd
import pyarrow as pa
import redis
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)
def save_df_to_redis(r, redis_key, df):
buffer = pa.serialize_pandas(df)
r.set(redis_key, buffer.to_pybytes())
def load_df_from_redis(r, redis_key):
buffer = r.get(redis_key)
df = pa.deserialize_pandas(buffer)
return df
data = {
"Name": ["John", "Anna", "Peter"],
"Age": [28, 24, 33],
}
df = pd.DataFrame(data)
save_df_to_redis(r, "key", df)
df_redis = load_df_from_redis(r, "key")
print(df_redis)