pandas:数据列的压缩与扩展

标题有点太抽象了,其实是因为我最近遇上两个需求:
一个是将一些以1min为单位的时间序列存储成blob类型存入mysql(压缩),并且以序号和日期为主键。同时写一个api将其读取并还原(扩展)
二个是写一个api,输入为有效期范围(startDate和EndDate)和序号(stock_code),输出为每个序号在有效期范围内(扩展),每日涉及到的内容(concept_code),其中内容以list返回(压缩),且序号和日期组成组件

先说第一部分:
压缩

all_index_info = [] # blob数据的容器
def get_all_index_data():
    # 以序号和日期为主键,分组传参
	all_index_minute_price.groupby(['index_code','trade_date'],as_index=False).apply(lambda x:data_to_string(x)) 
	data = pd.DataFrame(all_index_info) # 转为DataFrame
def data_to_string(each_data):
    index_info = {}
    index_info['index_code'] = normalize_code_dg(each_data['index_code'].tolist()[0])# 序号
    index_info['trade_date'] = each_data['trade_date'].tolist()[0]# 日期
    index_info['open_minute'] = np.array(each_data['open']).astype(np.float32).tostring()# 将数据转为字符串(即我说的压缩)
    index_info['open_minute'] = np.array(each_data['open']).astype(np.float32).tostring()
    index_info['high_minute'] = np.array(each_data['high']).astype(np.float32).tostring()
    index_info['low_minute'] = np.array(each_data['low']).astype(np.float32).tostring()
    index_info['turnover_share_minute'] = np.array(each_data['volume']).astype(np.float32).tostring()
    index_info['turnover_value_minute'] = np.array(each_data['money']).astype(np.float32).tostring()
    all_index_info.append(index_info)

扩展

def minutes_data_decoder(raw_data = pd.DataFrame()):
    """

    Args:
        raw_data: 带有分钟数据的dataframe

    Returns:
        df_result: decode之后的包含分钟数据的DataFrame

    """
    data_index = raw_data.index.values.tolist() # 取出序号
    raw_data = raw_data.reset_index(drop=True)# 删除索引
    for data_column in raw_data.columns.values:
        if data_column[-6:] == 'minute': #若为分钟数据
            name_list = []
            for i in range(1, 241): # open_minute_001,open_minute_002...
                name_list.append(data_column + '_' + str(i).zfill(3))
            tmp = pd.DataFrame([x.tolist() for x in raw_data[data_column].apply(_bytes_decode).values],
                               columns=name_list)
            raw_data = pd.concat([raw_data, tmp], axis=1)# 横向扩展
            raw_data = raw_data.drop(columns=[data_column])
    data = raw_data.set_index(pd.Index(data_index))
    data = data.rename_axis(['stock_code','trade_date'])
    return data

##分钟数据转换为原始数据
def _bytes_decode(close_minute):
    try:
        close_minute = np.frombuffer(close_minute, dtype=np.float32)
    except:
        close_minute = np.array([])
    return close_minute

第二部分:
原始数据是这样:

之前我想要达到的效果:
在这里插入图片描述这是我的解决办法:

def deal(result,):
	result.loc[pd.to_datetime(result['startDate'],format='%Y-%m-%d') < pd.to_datetime(trade_date_list[0][0],format='%Y-%m-%d'),'startDate'] = pd.to_datetime(trade_date_list[0][0],format='%Y-%m-%d')# 比较前先转换时间格式
	result.loc[pd.to_datetime(result['endDate'],format='%Y-%m-%d') > pd.to_datetime(trade_date_list[-1][-1],format='%Y-%m-%d'),'endDate'] = pd.to_datetime(trade_date_list[-1][-1],format='%Y-%m-%d')
	temp = result.apply(lambda x:pd.Series(pd.date_range(x['startDate'],x['endDate'])),axis=1).stack().reset_index(level=1) # 将生成的时间Series化后,用stack将列索引转为行索引后重设索引(扩展)
	result = pd.concat([result,temp],axis=1).drop(['startDate','endDate','level_1'],axis=1).rename(columns={0:'trade_date'})   #使用concat根据索引对齐
	result = result.groupby(['stock_code','trade_date'],as_index=False).apply(lambda x:x['concept_code'].drop_duplicates().tolist()).reset_index().rename(columns={0:'concept_code'}) #按“输入值+时间”分组,将组内代码去重后转化为list,再重设索引(压缩)

那如何还原呢?

# 将字符串类型的list(放入csv之后再读出来就变成字符串类型的list)转为list,再转为series
concept_code_series = data.apply(lambda x:pd.Series(eval(x['concept_code'])),axis=1)
# 将concept_code与index对齐
result = pd.concat([data[['stock_code','trade_date']],concept_code_series ])
# 列索引转行索引
result = result.stack()
# 取消索引
result = result.reset_index(level=0).rename(columns={0:'concept_code'})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值