python中Pandas做处理时内存节省的技巧

python中Pandas做处理时内存节省的技巧

1.查看dataframe占用空间

例如,我们读取之前的所有行情和因子数据:
data = pd.read_csv('total_data.csv', index_col=0)
data.info(memory_usage='deep')    
    首先,我们读取total_data.csv这个数据,并制定第一列是index,然后,我们获取一下这个dataframe这个对象在内存中的情况。

<class 'pandas.core.frame.DataFrame'>
Int64Index: 91427 entries, 6095 to 91426
Data columns (total 13 columns):
date            91427 non-null object
open            91427 non-null float64
close           91427 non-null float64
high            91427 non-null float64
low             91427 non-null float64
volume          91427 non-null float64
openinterest    91427 non-null int64
raw_factor      91427 non-null float64
sec_id          91427 non-null object
win_secore      91427 non-null float64
z-score         91427 non-null float64
group           91427 non-null int64
neuted_score    78408 non-null float64
dtypes: float64(9), int64(2), object(2)
memory usage: 14.4 MB
我们可以看到,这个dataframe每一列的数据类型,以及,一共占用的内存空间:14.4M。看起来不大的样子。别忘了,我们这里是令标的池为sz50,同时只有一个因子。某种意义上,完全没有意义,笔者只是为了展示多因子模型的整个流程和框架罢了,对于50个股票的标的池,做多因子策略,几乎是没有任何意义的。我们想一想,如果范围是全市场,3000个股票,那么大概就是864M,而且这仅仅是一个因子。如果我们需要把100个因子的内容load到内存中,虽然有时候并不需要这样,那么就是8G,好吧,内存就不够了。

2.时间的处理

大家把数据本地化为csv,然后读取的时候,尽可能养成一个习惯,就是把时间那一列变成timestamp格式。这样有两个好处,一个是存储空间会减小,同时检索的速度会快,而且会减少很多不必要的错误。

csv读取进来的时候,默认时间是str格式,这一格式在pandas中被存储为object格式,还是很占内存的。

data[‘date’] = pd.to_datetime(data[‘date’])
然后我们在info一下,就是下面这样了:


```python
<class 'pandas.core.frame.DataFrame'>
Int64Index: 91427 entries, 6095 to 91426
Data columns (total 13 columns):
date            91427 non-null datetime64[ns]
open            91427 non-null float64
close           91427 non-null float64
high            91427 non-null float64
low             91427 non-null float64
volume          91427 non-null float64
openinterest    91427 non-null int64
raw_factor      91427 non-null float64
sec_id          91427 non-null object
win_secore      91427 non-null float64
z-score         91427 non-null float64
group           91427 non-null int64
neuted_score    78408 non-null float64
dtypes: datetime64[ns](1), float64(9), int64(2), object(1)
memory usage: 12.0 MB
    我们看到,内存占用少了2M+,这是个不错的现象。
3.修改数字

   其实,pandas在读取csv的时候,可以定义读取每一列的类型的,我们看到上面默认是float64,对于整数,默认是int64,知道一点计算机知识的都明白,很多时候我们是不需要这么float64这么大的存储范围的。

假设,我们一开始就定义好浮点数列的数据类型为float16


data = pd.read_csv('total_data.csv', index_col=0, dtype={'open': 'float16', 'close': 'float16', 'high': 'float16', 'low': 'float16','volume': 'float32',
                                                         'openinterest': 'int','raw_factor':  'float16','win_secore':   'float16', 'neuted_score':   'float16','z-score': 'float16'
                                                        })
然后info一下,

<class 'pandas.core.frame.DataFrame'>
Int64Index: 91427 entries, 6095 to 91426
Data columns (total 13 columns):
date            91427 non-null datetime64[ns]
open            91427 non-null float16
close           91427 non-null float16
high            91427 non-null float16
low             91427 non-null float16
volume          91427 non-null float32
openinterest    91427 non-null int32
raw_factor      91427 non-null float16
sec_id          91427 non-null object
win_secore      91427 non-null float16
z-score         91427 non-null float16
group           91427 non-null int64
neuted_score    78408 non-null float16
dtypes: datetime64[ns](1), float16(8), float32(1), int32(1), int64(1), object(1)
memory usage: 7.1 MB
现在,内存占用只有7.1M了,连原来的一半都不到。
4.catrgory类

    然后是最后一个大杀器,就是当某一列中,有很多重复元素的时候,其实必然是存在冗余的,比如,我们的dataframe中股票代码,sec_id和行业类别,group这两列,肯定有很多重复的,那么,我们就可以把这两列设置为category类,这一类本质上就是一个字典的映射。


data['group'] = data['group'].astype('category')
data['sec_id'] = data['sec_id'].astype('category')
然后,我们看一下效果:

```python
<class'pandas.core.frame.DataFrame'>

Int64Index: 91427entries, 6095 to 91426

Data columns(total 13 columns):

date            91427 non-null datetime64[ns]

open            91427 non-null float16

close           91427 non-null float16

high            91427 non-null float16

low             91427 non-null float16

volume          91427 non-null float32

openinterest    91427 non-null int32

raw_factor      91427 non-null float16

sec_id          91427 non-null category

win_secore      91427 non-null float16

z-score         91427 non-null float16

group           91427 non-null category

neuted_score    78408 non-null float16

dtypes:category(2), datetime64[ns](1), float16(8), float32(1), int32(1)

memory usage: 3.7MB
居然只占用了3.7M!连原来的个位数都不到。

5.注意:

当然,笔者这里要说明的是,如果你把上面这样做过处理的dataframe直接放进alphalens或者用别的一些数学性很强的包进行运算,比如用statismodules进行回归,就会有错误。所以,通常的使用场景就是仅仅需要对数据做简单的处理,但是数据很分散,需要多次读取,但是精度又不高,这个时候,如果不做上面这样的处理,多进程由于受到内存限制,可能没有任何速度的提升,但是经过上面的处理,单个处理的内存和cpu都会降低,这个时候就可以多进程并发,加快速度了。

原文:https://blog.csdn.net/qtlyx/article/details/78003109

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值