基于python对tushare股票数据进行数据分析

认识tushare数据 官网

[https://tushare.pro/document/2?doc_id=185]

网站主要是对数据的字段进行标识 

1.导入相关的库

import tushare as ts
import pandas as pd
import matplotlib.pyplot as plt
# 需要进行实例化
pro = ts.pro_api('fe1b444718e3b571becb921a05d7efc965e3bfadcf342fac2cd2dd76')  
 # 注意:这个token可能会由于使用人数过多失效,建议自己申请下,高校师生免费,请联系官方客服:https://tushare.pro/document/1

2.导入这里要用到的数据

2.1 利润表的导入字段的修改

df = pd.DataFrame()
df = pro.income(ts_code='000651.SZ', start_date='20180101', end_date='20221231', fields='ts_code,int_exp,operate_profit,end_date,revenue,total_revenue,total_cogs,n_income,n_income_attr_p,ebit')
df.head(5)
# #修改英文字段名为中文字段名
states={
        'ts_code':'TS指数代码',
        'int_exp':'减:利息支出',
        'operate_profit':'营业利润',
        'end_date':'公告结束日期',
        'total_revenue':'营业总收入',
        'revenue':'营业收入',
        'total_cogs':'营业总成本',
        'n_income':'净利润',
        'n_income_attr_p':'净利润(不含少数股东损益)',
        'ebit':'息税前利润'}
df.rename(columns=states,inplace=True)
df.head()    

在这里插入图片描述

2.2 资产负债表的导入字段的修改

df1 = pd.DataFrame()
df1 = pro.balancesheet(ts_code='000651.SZ', start_date='20180101', end_date='20221231', fields='ts_code,accounts_receiv,total_cur_liab,prepayment,total_cur_assets,end_date,money_cap,fix_assets,inventories,total_hldr_eqy_exc_min_int,total_hldr_eqy_inc_min_int,total_liab,total_assets')
df1.head(5)
# #修改英文字段名为中文字段名
states={
        'ts_code':'TS指数代码',
        'end_date':'公告结束日期',
        'money_cap':'货币资金',
        'inventories':'存货',
        'total_cur_liab':'流动负债合计',
        'prepayment':'预付款项',
        'total_hldr_eqy_exc_min_int':'股东权益合计(不含少数股东权益)',
        'total_hldr_eqy_inc_min_int':'股东权益合计(含少数股东权益)',
        'accounts_receiv':'应收账款',
        'total_cur_assets':'流动资产合计',
        'fix_assets':'固定资产',
        'total_assets':'资产总计',
        'total_liab':'负债合计'}
df1.rename(columns=states,inplace=True)
df1.head()    

在这里插入图片描述

2.3 现金流量表的导入字段的修改

df2 = pd.DataFrame()
df2 = pro.cashflow(ts_code='000651.SZ', start_date='20180101', end_date='20221231', fields='ts_code,end_date,n_cashflow_act,n_cashflow_inv_act,n_cash_flows_fnc_act')
df2.head(5)
# #修改英文字段名为中文字段名
states={
        'ts_code':'TS指数代码',
        'end_date':'公告结束日期',
        'n_cashflow_act':'经营活动产生的现金流量净额',
        'n_cashflow_inv_act':'收到其他与投资活动有关的现金',
        'n_cash_flows_fnc_act':'筹资活动产生的现金流量净额'}
df2.rename(columns=states,inplace=True)
df2.head()    

在这里插入图片描述

2.4 合并前两个表格

df3 = pd.merge(df, df1, how='outer')

data = pd.merge(df2, df3, how='outer')
data.head(5)

在这里插入图片描述

3.数据处理

3.1 处理重复值

根据公告结束日期 进行去重
# 根据指定列名(column_name)删除重复行
data = data.drop_duplicates(subset=['公告结束日期'])
data.head(10)

在这里插入图片描述

3.2 将年份划分开来 这里润用到取某字段的前四个字符

data['年份'] = data['公告结束日期'].str.slice(0, 4)

3.3 将么每个字段通过相同的年龄 取平均值

average_values = data.groupby('年龄')[['经营活动产生的现金流量净额','营业利润','减:利息支出','预付款项','收到其他与投资活动有关的现金','流动资产合计','流动负债合计','应收账款','股东权益合计(不含少数股东权益)','股东权益合计(含少数股东权益)','筹资活动产生的现金流量净额','营业总收入','营业收入','营业总成本','净利润','净利润(不含少数股东损益)','息税前利润','货币资金','存货','固定资产','资产总计','负债合计']].mean()
average_values
average_df = pd.DataFrame(average_values)

在这里插入图片描述

	将股票的编号插进去 平均值求取的时候 将编号剔除掉了

average_df.insert(loc=1, column='TS指数代码', value='000651.SZ')

在这里插入图片描述

插入年份

average_df.insert(loc=1, column='年份', value=['2017','2018','2019','2020','2021','2022'])

取为2017年的数据 并赋值 后面计算时用的到
df_2017 = average_df['股东权益合计(不含少数股东权益)'][:1]['2017'] 
# 进行删除 删除2017年的数据

4.开始画图发分析

4.1 计算毛利率

average_df['毛利率'] = round((average_df['营业收入']-average_df['营业总成本'])/average_df['营业收入'],4) 

在这里插入图片描述

from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(12)
plt.title("财经分析图")
plt.plot(average_df['年份'],average_df['毛利率'],label= '毛利率')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

4.2 计算营业利润率

# 先计算营业利润
average_df['营业利润率'] = round((average_df['营业利润']) / average_df['营业收入'], 4)

在这里插入图片描述

plt.figure(12)
plt.title("财经分析图")
plt.plot(average_df['年份'],average_df['营业利润率'],label= '营业利润率')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

4.3 计算净利润率

average_df['净利润率'] = round((average_df['净利润'])/average_df['营业收入'],4) 

在这里插入图片描述

plt.figure(12)
plt.title("财经分析图")
plt.plot(average_df['年份'],average_df['净利润率'],label= '净利润率')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

4.4 计算净资产收益率

这里就要用到前面保留的2017年的数据
asset1 = average_df['股东权益合计(不含少数股东权益)'][1:].to_list()
asset1.append(df_2017)
average_df['股东权益(上期余额)'] = asset1

average_df['ROE'] = round(average_df['净利润(不含少数股东损益)'] / ((average_df['股东权益合计(不含少数股东权益)'] + average_df['股东权益(上期余额)']) / 2), 4)

在这里插入图片描述

plt.figure(12)
plt.title("财经分析图")
plt.plot(average_df['年份'],average_df['ROE'],label= '净资产收益率')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

4.5 计算存货周转率

# 存货周转率
# 获取2017年的存货数据
df_2017 = pro.balancesheet(ts_code='000651.SZ', period='20141231')[-1:]
inv_2017 = df_2017['inventories'].iloc[0]
# 把2014年~2018年的存货作为新列表,并把列表加入表格
inv0 = average_df['存货'][1:].to_list()
inv0.append(inv_2017)
average_df['存货(上期余额)'] = inv0
# 计算存货周转率
average_df['存货周转率'] = round(average_df['营业总成本'] / ((average_df['存货'] + average_df['存货(上期余额)']) / 2), 4)

在这里插入图片描述

plt.figure(12)
plt.title("财经分析图")
plt.plot(average_df['年份'],average_df['存货周转率'],label= '存货周转率')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

4.6 总资产周转率

# 总资产周转率
# 获取2017年的总资产数据
df_2017 = pro.balancesheet(ts_code='000651.SZ', period='20171231')[-1:]
inv_2017 = df_2017['total_assets'].iloc[0]
inv0 = average_df['资产总计'][1:].to_list()
inv0.append(inv_2017)
average_df['资产总计(上期余额)'] = inv0
# 计算存货周转率
average_df['总资产周转率'] = round(average_df['营业收入'] / ((average_df['资产总计'] + average_df['资产总计(上期余额)']) / 2), 4)

在这里插入图片描述

plt.figure(12)
plt.title("财经分析图")
plt.plot(average_df['年份'],average_df['总资产周转率'],label= '总资产周转率')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

4.7 获取2017年的应收账款数据

# 获取2017年的应收账款数据
df_2017 = pro.balancesheet(ts_code='000651.SZ', period='20171231')[-1:]
inv_2017 = df_2017['accounts_receiv'].iloc[0]
inv0 = average_df['应收账款'][1:].to_list()
inv0.append(inv_2017)
average_df['应收账款(上期余额)'] = inv0
# 计算存货周转率
average_df['应收账款周转率'] = round(average_df['营业收入'] / ((average_df['应收账款'] + average_df['应收账款(上期余额)']) / 2), 4)

在这里插入图片描述

plt.figure(12)
plt.title("财经分析图")
plt.plot(average_df['年份'],average_df['应收账款周转率'],label= '应收账款周转率')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

5 分析同行股票 并进行打分

# 导入相关库
import pandas as pd
import numpy as np
import tushare as ts
import matplotlib.pyplot as plt

# 输入tushare密钥,下面这个token可能会由于使用人数过多失效,建议自己申请下,高校师生免费,请联系官方客服:https://tushare.pro/document/1
pro = ts.pro_api('fe1b444718e3b571becb921a05d7efc965e3bfadcf342fac2cd2dd76')


# 定义获取三张报表的函数
def access_data(comps, codes, years):
    # 定义列重命名函数,把列名自动改为中文名
    def rename_col(data):
        rename_sheet = pd.read_excel('重命名(1).xlsx')
        eng = rename_sheet['名称'].tolist()
        chi = rename_sheet['描述'].tolist()
        re_dict = dict(zip(eng, chi))
        data = data.rename(columns=re_dict)
        return data

    for i in range(len(comps)):
        # 各新建一个空DataFrame
        df_balance = pd.DataFrame()
        df_income = pd.DataFrame()
        df_cash = pd.DataFrame()
        for year in years:
            df_balance0 = pro.balancesheet(ts_code=codes[i], period=str(year) + '1231')[-1:]
            df_income0 = pro.income(ts_code=codes[i], period=str(year) + '1231')[-1:]
            df_cash0 = pro.cashflow(ts_code=codes[i], period=str(year) + '1231')[-1:]
            # 拼接各年份报表
            df_balance = df_balance.append(df_balance0)
            df_income = df_income.append(df_income0)
            df_cash = df_cash.append(df_cash0)
        # 更改索引名称
        df_balance = rename_col(df_balance)
        df_income = rename_col(df_income)
        df_cash = rename_col(df_cash)
        # 保存为表格
        if '*' in comps[i]:  # 防止公司名称里有*,例如2022年的*ST皇台,*ST表示有退市风险,但是文件名不可以有*号,所以做替换处理
            comps[i] = comps[i].replace('*', '')
        writer = pd.ExcelWriter(comps[i] + '.xlsx')
        df_balance.to_excel(writer, '资产负债表', index=False)
        df_income.to_excel(writer, '利润表', index=False)
        df_cash.to_excel(writer, '现金流量表', index=False)
        writer.save()
# 定义财务比率表生成函数
def ratio_sheet(comp):
    # 读取报表数据
    df_balancesheet = pd.read_excel(comp + '.xlsx', sheet_name='资产负债表')
    df_income = pd.read_excel(comp + '.xlsx', sheet_name='利润表')
    df_cashflow = pd.read_excel(comp + '.xlsx', sheet_name='现金流量表')
    # 报表拼接
    data = pd.merge(df_income, df_balancesheet, on=['报告期', 'TS股票代码', '公告日期', '实际公告日期', '报表类型', '公司类型'])
    data = pd.merge(data, df_cashflow, on=['报告期', 'TS股票代码', '公告日期', '实际公告日期', '报表类型', '公司类型'])
    # 把空值填充为0,防止计算出错
    data = data.fillna(0)
    # 把相关数据的上期余额加入新表,包括股东权益、存货、资产总计、应收账款、营业收入、营业利润、负债合计
    columns0 = ['股东权益合计(不含少数股东权益)', '存货', '资产总计', '应收账款', '营业收入', '营业利润', '负债合计', '净利润(不含少数股东损益)']
    for column in columns0:
        data[column + '(上期)'] = data[column].shift(-1)
    # 只取前五行数据保存用来做演示,不要最后一行数据了(因为它没有上期数据)
    data = data[0:5]
    # 计算各项指标
    # 盈利能力
    data['毛利率'] = round((data['营业收入'] - data['减:营业成本']) / data['营业收入'], 4)
    data['营业利润率'] = round((data['营业利润']) / data['营业收入'], 4)
    data['净利润率'] = round(data['净利润(含少数股东损益)'] / data['营业收入'], 4)
    data['ROE'] = round(data['净利润(不含少数股东损益)'] / ((data['股东权益合计(不含少数股东权益)'] + data['股东权益合计(不含少数股东权益)']) / 2), 4)
    # 营运能力
    data['存货周转率'] = round(data['减:营业成本'] / ((data['存货'] + data['存货(上期)']) / 2), 4)
    data['总资产周转率'] = round(data['营业收入'] / ((data['资产总计'] + data['资产总计(上期)']) / 2), 4)
    data['应收账款周转率'] = round(data['营业收入'] / ((data['应收账款'] + data['应收账款(上期)']) / 2), 4)
    # 偿债能力
    data['流动比率'] = round(data['流动资产合计'] / data['流动负债合计'], 4)
    data['速动比率'] = round((data['流动资产合计'] - data['存货'] - data['预付款项']) / data['流动负债合计'], 4)
    data['利息保障倍数'] = round(data['息税前利润'] / (-data['减:财务费用']), 4)
    # 成长能力
    data['营业收入增长率'] = round((data['营业收入'] - data['营业收入(上期)']) / data['营业收入(上期)'], 4)
    data['营业利润增长率'] = round((data['营业利润'] - data['营业利润(上期)']) / data['营业利润(上期)'], 4)
    data['净利润增长率'] = round((data['净利润(不含少数股东损益)'] - data['净利润(不含少数股东损益)(上期)']) / data['净利润(不含少数股东损益)(上期)'], 4)
    # 取出财务比率
    df_ratio = data[
        ['报告期', '毛利率', '营业利润率', '净利润率', 'ROE', '存货周转率', '总资产周转率', '应收账款周转率', '流动比率', '速动比率', '利息保障倍数', '营业收入增长率',
         '营业利润增长率', '净利润增长率']]
    df_ratio = df_ratio.T  # 转置

    # 因为上一行代码转置之后,第一行是0/1/2/3……,我们希望把第二行的报告期作为表头,并从第二行开始取数
    df_ratio.columns = df_ratio.iloc[0].apply(lambda x: int(x))  # 重新命名表头,并且通过apply+lambda配合int取整函数将日期变成整数格式(原本保存成了小数格式)
    df_ratio = df_ratio[1:]

    # 把财务比率保存为现有表格中的sheet
    if '*' in comp:  # 防止公司名称里有*,例如2022年的*ST皇台,*ST表示有退市风险,但是文件名不可以有*号,所以做替换处理
        comp = comp.replace('*', '')

    writer = pd.ExcelWriter(comp + '.xlsx', mode="a", engine="openpyxl")
    df_ratio.to_excel(writer, '财务比率表')
    writer.save()

# 获取同行业股票代码
com_data = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
bj_com = com_data[com_data['industry'] == '家用电器']
bj_code = bj_com['ts_code'].tolist()
bj_name = bj_com['name'].tolist()

years = [2020, 2019, 2018, 2017, 2016, 2015]
# 调用函数,生成财务比率表
access_data(bj_name, bj_code, years)

for comp in bj_name:
    ratio_sheet(comp)

# 制作汇总表
ratio_ind = pd.DataFrame()
for name in bj_name:
    # 读取财务比率表数据,这部分内容不熟悉的可以复习下上一章
    df_ratio = pd.read_excel( name + '.xlsx', sheet_name='财务比率表')
    df_ratio = df_ratio.rename(columns={'Unnamed: 0': '报告期'})  # 第一列列名是unnamed:0,这里换成报告期
    print(df_ratio)
    df_ratio = df_ratio.set_index('报告期')
    # print(df_ratio)
    meanvalue = df_ratio.T.mean()  # 取多年的平均值
    df_ratio[name] = meanvalue
    ratio_ind = ratio_ind.append(df_ratio[[name]].T)
# ratio_ind['公司名称'] = bj_name
print(ratio_ind)
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值