matplotlib日期坐标轴及dataframe的merge操作Demo

1.主要问题

主要记录dataframe构造,非连续时间做X轴的处理以及pandas中dataframe的连接操作。

2.Demo代码

# coding:utf8
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime
import matplotlib.dates as mdates


# 方法1: 默认index是X轴 达到预期
def p1():
    ax = fig.add_subplot(311)
    ax.plot(df_days['data'], label='data')  # 默认以index作为x轴

    for a, b in zip(df_days.index.to_list(), df_days['data']):
        ax.text(a, b, '{:,.2f}'.format(b), ha='center', fontsize=14, va='bottom', color='blue')

    # 画X轴刻度及label
    # 方法1:用plt.xticks
    # xticks两个参数只在plt有,同时设置刻度跟标签
    plt.xticks(df_days.index.to_list(), xlabels, rotation=90)
    # ax.xticks(df_days.index.to_list(), xlabels, rotation=90)
    # #AttributeError: 'AxesSubplot' object has no attribute 'xticks'

    # 画X轴刻度及label
    # 方法2:用ax.set_xticks及ax.set_xticklabels
    # ax的ticks跟tickslabel要分开设置!!!
    # ax.set_xticks(df_days.index.to_list())  # Index作刻度
    # ax.set_xticklabels(xlabels, rotation=30)

    ax.grid()
    ax.legend()


# 方法3:用非index做X轴,若是日期型,或者mdate.date2num转数字为x轴tick,去掉的周末会留空,非预期
def p2():
    ax = fig.add_subplot(312)
    # plt.plot(df_days["trd_date"], df_days['data'], label='data')
    # 等价于,日期即转不转数字,内部都是以数字处理,即当前日期与"0000-01-01 00:00:00"相减的天数
    plt.plot(df_days["trd_date"].map(lambda x: mdates.date2num(x)), df_days['data'], label='data')

    for a, b in zip(df_days["trd_date"], df_days['data']):
        ax.text(mdates.date2num(a), b, '{:,.2f}'.format(b), ha='center', fontsize=14, va='bottom')

    plt.xticks(df_days["trd_date"], xlabels, rotation=45)
    ax.grid()
    ax.legend()


# 方法3:用非Index做X轴,且非日期型 达到预期
def p3():
    ax = fig.add_subplot(313)
    ax.plot(xlabels, df_days['data'], label='data')

    for a, b in zip(df_days.index.to_list(), df_days['data']):
        ax.text(a, b, '{:,.2f}'.format(b), ha='center', fontsize=14, va='bottom')

    ax.set_xticklabels(xlabels, rotation=35)
    ax.grid()
    ax.legend()


def get_df_without_56(days=29):
    # 起始日期
    start_date = datetime.date.today() - datetime.timedelta(days=days)
    # 日期序列
    day_list = pd.date_range(start_date, periods=days, freq='D')
    # 序列里直接过滤掉周末
    day_list = day_list[day_list.weekday < 5]
    # 生产随机Demo数据
    data_list = np.random.rand(days - int(days / 7) * 2) * 100

    # 生成dataframe方法1:两步走
    df_days = pd.DataFrame(data=day_list, columns=['trd_date'])
    df_days['data'] = data_list  # 增加数据列
    return df_days


def get_df_without_01(days=29):
    # 起始日期
    start_date = datetime.date.today() - datetime.timedelta(days=days)
    # 日期序列
    day_list = pd.date_range(start_date, periods=days, freq='D')
    # 序列里直接过滤周一周二
    day_list = day_list[day_list.weekday > 1]
    # 生产随机Demo数据
    data_list = np.random.rand(days - int(days / 7) * 2) * 100

    # 生成dataframe方法2:zip后一步到位
    df_days = pd.DataFrame(list(zip(day_list, data_list)), columns=['trd_date', 'data'])
    return df_days


def df_merge_demo(left, right):
    # 默认以重叠的列名当做连接键,本例中等同于pd.merge(left,right,on=['trd_date','data'],how='inner')
    defaultmerge = pd.merge(left, right)
    print("\n测试:defaultmerge=pd.merge(left, right)")
    print(defaultmerge.head(100))

    # 等同于pd.concat([left,right]).reset_index(drop=True)
    defaultouter = pd.merge(left, right, how='outer')
    print("\n测试:defaultouter = pd.merge(left, right, how='outer')")
    print(defaultouter.head(100))
    pdconcat = pd.concat([left, right]).reset_index(drop=True)
    print("\n测试:pdconcat= pd.concat([left, right]).reset_index(drop=True)")
    print(pdconcat)

    # 如果两个对象的key列名不同,可以分别指定,例:pd.merge(left,right,left_on='lkey',right_on='rkey')
    leftjoin = pd.merge(left, right, on='trd_date', how='left')
    print("\n测试:leftjoin = pd.merge(left, right, on='trd_date', how='left')")
    print(leftjoin.head(100))
    # 多键连接时将连接键组成列表传入,例:pd.merge(left,right,on=['key1','key2']
    rightjoin = pd.merge(left, right, on='trd_date', how='right')
    print("\n测试:rightjoin = pd.merge(left, right, on='trd_date', how='right')")
    print(rightjoin.head(100))

    innerjoin = pd.merge(left, right, on='trd_date', how='inner')  # 默认为inner
    print("\n测试:innerjoin = pd.merge(left, right, on='trd_date', how='inner')")
    print(innerjoin.head(100))

    outerjoin = pd.merge(left, right, on='trd_date', how='outer')
    print("\n测试:innerjoin = pd.merge(left, right, on='trd_date', how='outer')")
    print(outerjoin.head(100))

    left = left.set_index('trd_date')  # 设置索引
    right = right.set_index('trd_date') # 设置索引
    # join连接后重建索引
    dfjoin = left.join(right, lsuffix='_l', rsuffix='_r',sort=False).reset_index()
    print("\n测试:dfjoin = left.join(right).reset_index()")
    print(dfjoin.head(100))
    dfjoin.rename(columns={'trd_date': '交易日期'}, inplace=True)  # 改列名
    print("\n测试:dfjoin.rename(columns={'trd_date': '交易日期'}, inplace=True)  # 改列名")
    print(dfjoin.head(100))


if __name__ == '__main__':
    df_days = get_df_without_56(15)
    df_days_01 = get_df_without_01(15)

    # dataframe merge 测试
    df_merge_demo(df_days, df_days_01)

    fig = plt.figure(figsize=(20, 10), dpi=80)
    # 生成x轴的label,方法1: map然后lambda表达式
    xlabels = df_days["trd_date"].map(lambda x: x.strftime('%m-%d'))
    # 或者 方法2: for in 循环生成数组
    # xlabels = [date.strftime('%m-%d') for (date) in df_days["trd_date"]]

    p1()
    p2()
    p3()

    plt.show()
    plt.close()

3.执行结果

测试:defaultmerge=pd.merge(left, right)
Empty DataFrame
Columns: [trd_date, data]
Index: []
测试:defaultouter = pd.merge(left, right, how='outer')
     trd_date       data
0  2020-02-20  28.519733
1  2020-02-21  21.957296
2  2020-02-24  81.709042
3  2020-02-25  49.141968
4  2020-02-26  75.962113
5  2020-02-27  34.297047
6  2020-02-28   8.599335
7  2020-03-02  59.895028
8  2020-03-03  36.150423
9  2020-03-04  41.961246
10 2020-03-05  78.180868
11 2020-02-20  81.522147
12 2020-02-21  66.379312
13 2020-02-22  68.038422
14 2020-02-23  82.831858
15 2020-02-26  44.112500
16 2020-02-27   9.492410
17 2020-02-28  53.929783
18 2020-02-29  19.431358
19 2020-03-01  59.103261
20 2020-03-04  66.754922
21 2020-03-05  66.497167
测试:pdconcat= pd.concat([left, right]).reset_index(drop=True)
     trd_date       data
0  2020-02-20  28.519733
1  2020-02-21  21.957296
2  2020-02-24  81.709042
3  2020-02-25  49.141968
4  2020-02-26  75.962113
5  2020-02-27  34.297047
6  2020-02-28   8.599335
7  2020-03-02  59.895028
8  2020-03-03  36.150423
9  2020-03-04  41.961246
10 2020-03-05  78.180868
11 2020-02-20  81.522147
12 2020-02-21  66.379312
13 2020-02-22  68.038422
14 2020-02-23  82.831858
15 2020-02-26  44.112500
16 2020-02-27   9.492410
17 2020-02-28  53.929783
18 2020-02-29  19.431358
19 2020-03-01  59.103261
20 2020-03-04  66.754922
21 2020-03-05  66.497167
测试:leftjoin = pd.merge(left, right, on='trd_date', how='left')
     trd_date     data_x     data_y
0  2020-02-20  28.519733  81.522147
1  2020-02-21  21.957296  66.379312
2  2020-02-24  81.709042        NaN
3  2020-02-25  49.141968        NaN
4  2020-02-26  75.962113  44.112500
5  2020-02-27  34.297047   9.492410
6  2020-02-28   8.599335  53.929783
7  2020-03-02  59.895028        NaN
8  2020-03-03  36.150423        NaN
9  2020-03-04  41.961246  66.754922
10 2020-03-05  78.180868  66.497167
测试:rightjoin = pd.merge(left, right, on='trd_date', how='right')
     trd_date     data_x     data_y
0  2020-02-20  28.519733  81.522147
1  2020-02-21  21.957296  66.379312
2  2020-02-26  75.962113  44.112500
3  2020-02-27  34.297047   9.492410
4  2020-02-28   8.599335  53.929783
5  2020-03-04  41.961246  66.754922
6  2020-03-05  78.180868  66.497167
7  2020-02-22        NaN  68.038422
8  2020-02-23        NaN  82.831858
9  2020-02-29        NaN  19.431358
10 2020-03-01        NaN  59.103261
测试:innerjoin = pd.merge(left, right, on='trd_date', how='inner')
    trd_date     data_x     data_y
0 2020-02-20  28.519733  81.522147
1 2020-02-21  21.957296  66.379312
2 2020-02-26  75.962113  44.112500
3 2020-02-27  34.297047   9.492410
4 2020-02-28   8.599335  53.929783
5 2020-03-04  41.961246  66.754922
6 2020-03-05  78.180868  66.497167
测试:innerjoin = pd.merge(left, right, on='trd_date', how='outer')
     trd_date     data_x     data_y
0  2020-02-20  28.519733  81.522147
1  2020-02-21  21.957296  66.379312
2  2020-02-24  81.709042        NaN
3  2020-02-25  49.141968        NaN
4  2020-02-26  75.962113  44.112500
5  2020-02-27  34.297047   9.492410
6  2020-02-28   8.599335  53.929783
7  2020-03-02  59.895028        NaN
8  2020-03-03  36.150423        NaN
9  2020-03-04  41.961246  66.754922
10 2020-03-05  78.180868  66.497167
11 2020-02-22        NaN  68.038422
12 2020-02-23        NaN  82.831858
13 2020-02-29        NaN  19.431358
14 2020-03-01        NaN  59.103261
测试:dfjoin = left.join(right).reset_index()
     trd_date     data_l     data_r
0  2020-02-20  28.519733  81.522147
1  2020-02-21  21.957296  66.379312
2  2020-02-24  81.709042        NaN
3  2020-02-25  49.141968        NaN
4  2020-02-26  75.962113  44.112500
5  2020-02-27  34.297047   9.492410
6  2020-02-28   8.599335  53.929783
7  2020-03-02  59.895028        NaN
8  2020-03-03  36.150423        NaN
9  2020-03-04  41.961246  66.754922
10 2020-03-05  78.180868  66.497167
测试:dfjoin.rename(columns={'trd_date': '交易日期'}, inplace=True)  # 改列名
         交易日期     data_l     data_r
0  2020-02-20  28.519733  81.522147
1  2020-02-21  21.957296  66.379312
2  2020-02-24  81.709042        NaN
3  2020-02-25  49.141968        NaN
4  2020-02-26  75.962113  44.112500
5  2020-02-27  34.297047   9.492410
6  2020-02-28   8.599335  53.929783
7  2020-03-02  59.895028        NaN
8  2020-03-03  36.150423        NaN
9  2020-03-04  41.961246  66.754922
10 2020-03-05  78.180868  66.497167
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容