Monthly Archives: 十二月 2021

Hello World

pandas降低内存占用小技巧

这些年个人电脑的配置逐渐提高,服务器的配置反而停滞不前,自己手头的笔记本早就16G内存了,可公司用的阿里云的服务器,8G内存已经算“较高配置”了。。。
作为php、mysql之类的服务器,8G确实够用了,可做pandas数据分析,就不一定了,这不现在要做一个月度数据分析,要加载一个月的订单量,大概五千万量级,在本地虽然慢点,但结果都能跑出来,可到了服务器上,虽然linux开了虚拟内存,可不但比本地慢很多,还经常跑到半截被“killed”掉了。。。
“你被终结了,蠢货”,每到这个时候,就想起了星际里雷神的这句台词 O(∩_∩)O哈哈~
本地跑的时候,大概会占用12G内存,精简了不必要的字段以后,降低到了9G,还是不行,于是开始招其他能够降低内存占用的方法,比较有效的是修改数据类型,不过试了几次,int64改int16、int32,都没有效果,只有下面这个,让内存占从9G降低到了7、8G:
df['hour'] = df['hour'].astype(‘category’)
hour字段原本是字符串类型,直接.info(),显示是object,变成category以后,确实能节约不少空间
—————–先写到这里,后续验证有效的能减少内存占用的方法会持续更新(2021年12月21日17:07:05)

Hello World

Pandas双轴折线图生产与中文显示

双轴折线图,适合显示有两组不同类型,或者幅度差异较大的数据,这里展示的是一个对pandas生产双轴折线图的封装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# figsize 输出尺寸,默认1000×300
# savePath 保存路径
# title 折线图上显示的标题
# rightColumns 放在右侧的字段
# leftLabel  rightLabel  左右标签
def buildChartLine(dataDf, savePath, xInd='日期', figsize=(10, 3), title='', rightColumns=[], leftLabel='', rightLabel='', colors=[]):
    if isLocalServ(): # macos本地的中文配置
        plt.rcParams['font.sans-serif'] = ['SimHei']
        plt.rcParams['axes.unicode_minus'] = False
    else: # Linux的中文配置
        tfont = FontProperties(fname=r"/usr/share/fonts/simhei.ttf", size=14)
    dataDf.sort_values(xInd, inplace=True) # 确保顺序
    dataDf = dataDf.copy()
    dataDf.set_index(xInd, inplace=True) # 确保索引x轴字段名
    if len(colors) == 0:
        #TODO: 自定义颜色策略
        print('no color')
    plt.figure()
    if isLocalServ(): # macos本地的中文配置,和下面else里的,主要还是中文配置的差异,其他相同
        if len(rightColumns) > 0:
            ax = dataDf.plot(secondary_y=rightColumns, figsize=figsize, color=colors, kind='line')
            ax.right_ax.set_ylabel(rightLabel)
        else:
            ax = dataDf.plot(figsize=figsize, color=colors, kind='line')
        ax.set_ylabel(leftLabel)
        if len(title) > 0: ax.set(title=title)
        ax.legend(loc=2)
        plt.legend(loc=1)
    else:
        if len(rightColumns) > 0:
            ax = dataDf.plot(secondary_y=rightColumns, figsize=figsize, color=colors, kind='line')
            ax.right_ax.set_ylabel(rightLabel, fontproperties=tfont)
        else:
            ax = dataDf.plot(figsize=figsize, color=colors, kind='line')
        ax.set_ylabel(leftLabel, fontproperties=tfont)
        if len(title) > 0: plt.title(title, fontproperties=tfont)
        ax.legend(loc=2, prop=tfont)
        plt.legend(loc=1, prop=tfont)
    # plt.show() #直接显示折线图
    plt.savefig(savePath)

使用示例

1
2
3
4
5
6
7
dataDf = pd.DataFrame({
	'日期': ['2021-11-01', '2021-11-02', '2021-11-04',  '2021-11-06',  '2021-11-03',  '2021-11-05'],
	'风力': [3, 4, 5, 7, 9,	1],
	'最高温度': [13, 24, 25, 27, 19, 21],
	'最低温度': [1, 4, 5, 7, 9, 2]},
	columns=['日期', '风力', '最高温度', '最低温度'])
buildChartLine(dataDf, 'dayInfo', xInd='日期', figsize=(10, 3), title='气象记录', rightColumns=['风力'], leftLabel='温度(℃)', rightLabel='风力(级)', colors=['#fb0320', '#e50ce2', '#770ce5'])

实际效果:

小结:搞定这个双轴折线图过程中,主要碰到了两个问题:
1. pandas plot网上资料很多,但可能是因为版本的问题,大部分直接拿过来用,是用不了的,最终拼凑出上面的方法
2. linux里中文的解决。本来想让运维协助配置linux本地字库,无奈运维搞了半天也没效果,最终只能写死字库位置这个方案;另外一个比较坑的地方,同样是字体的定义,label/title那里参数名叫fontproperties,到了legend又叫prop。。。
—–
over
转载请注明出处:http://www.jiangkl.com/2021/12/pandas_iine_font/