与企业经营活动有关的资产如货币资金、交易性金融资产、应收票据、应收账款、应收款项融资、预付款项、存货、合同资产、长期应收款、固定资产、在建工程、使用权资产、无形资产、长期待摊费用以及递延所得税资产等。
对于投资者来说,可以通过准货币资金、应收账款、预付款项以及固定资产在总资产中的占比,开快速了解一家企业的资产质量。
本节,小鱼就和大家一起学习资产质量的分析~
一. 准备工作
导入 Python 工具包,对 pandas 和 matplotlib 的展示进行设置,读取配置文件 ./ini_debt_1.json
和财报数据 data.csv
。
注:有关 data.csv 文件的生成,需要的读者可朋友可移步至本连载的 【财报分析】读取和处理财报数据 一文进行学习。
import json
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option('display.float_format', lambda x: '%.2f' % x)
pd.set_option('mode.chained_assignment', None)
# 解决绘图中显示中文的问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
with open('./ini_debt_1.json', encoding='utf-8') as f:
config = json.load(f)
df = pd.read_csv('data.csv', index_col=0)
images = config['images']
titles = config['titles']
tables_fields = config['tables_fields']
其中配置文件 ./ini_debt_1.json
内容如下:
{
"images": [
"准货币资金占总资产的比率",
"应收账款与合同资产占总资产的比率",
"预付款项占总资产的比率",
"固定资产工程占总资产的比率"
],
"titles": [
"准货币资金占总资产的比率",
"应收账款与合同资产占总资产的比率",
"预付款项占总资产的比率",
"固定资产工程占总资产的比率"
],
"tables_fields": {
"t1": {
"columns": ["货币资金(元)", "交易性金融资产(元)", "其他流动资产里的理财产品", "其他流动资产里的结构性存款", "准货币资金", "资产合计(元)", "准货币资金占总资产的比率"],
"auto": ["货币资金(元)", "交易性金融资产(元)", "其他流动资产里的理财产品", "其他流动资产里的结构性存款", "资产合计(元)"]
},
"t2": {
"columns": ["应收账款(元)", "合同资产(元)", "应收账款加合同资产", "资产合计(元)", "应收账款占总资产的比率"],
"auto": ["应收账款(元)", "合同资产(元)", "资产合计(元)"]
},
"t3": {
"columns": ["预付款项(元)", "资产合计(元)", "预付款项占总资产的比率"],
"auto": ["预付款项(元)", "资产合计(元)"]
},
"t4": {
"columns": ["固定资产合计(元)", "在建工程合计(元)", "工程物资", "固定资产+在建工程+工程物资", "资产合计(元)", "固定资产工程占总资产的比率"],
"auto": ["固定资产合计(元)", "在建工程合计(元)", "工程物资", "资产合计(元)"]
}
}
}
下面的函数可以直接使用,init_table
根据配置文件生成表格,plot_show
进行画图展示,format_show_table
在展示表格时,将金额以千分位显示,占比比百分制显示。
def init_table(table_index):
t = pd.DataFrame(
index=df.index,
columns=tables_fields[table_index]['columns']
)
t[tables_fields[table_index]['auto']] = df[tables_fields[table_index]['auto']]
return t
def plot_show(t, title='', y_label='单位:亿', kind='bar', y_format='hundred million', pct_chage=False):
if title.endswith('率'):
y_label=''
y_format=''
ax1 = plt.subplot(111)
xticks = np.array(t.index)
ax1.set_ylabel(y_label)
if type(t) == pd.Series:
ax1.bar(xticks, t.values, width=0.5)
else:
t.plot(kind=kind, ax=ax1, rot=0)
y1_max = t.max()
y1_min = t.min()
while type(y1_max) == pd.Series:
y1_max = y1_max.max()
y1_min = y1_min.min()
if y1_min > 0:
y1_min = 0
y1_yticks = np.linspace(y1_min, y1_max, 8)
if y_format == 'hundred million':
plt.yticks(y1_yticks, map(lambda x:round(x/100000000,2), y1_yticks))
else:
plt.yticks(y1_yticks, map(lambda x:format(x,'.2%'), y1_yticks))
if type(t) == pd.Series and pct_chage:
ax2 = ax1.twinx()
ax2.set_ylabel('环比增长率')
y2 = t.pct_change().values
ax2.plot(xticks, y2, linewidth=2.5, color='xkcd:light blue')
y2_min = 0 if t.pct_change().min() > 0 else t.pct_change().min()
y2_max = t.pct_change().max() + 0.1
y2_yticks = np.linspace(y2_min, y2_max, 8)
plt.yticks(y2_yticks, map(lambda x:format(x,'.2%'), y2_yticks))
plt.title(title)
plt.savefig(title+'.png')
def format_thousandth(arr):
"""将 arr 或 Series 中的数字使用千分位表示"""
return arr.apply(lambda x:format(x, ',.0f'))
def format_percentage(arr):
"""将 arr 或 Series 中的数字使用百分制表示,小数点后保留 2 位"""
return arr.apply(lambda x:format(x, '.2%'))
def format_show_table(table,ignore=None):
table = table.copy()
for column in table.columns:
if ignore and column in ignore:
continue
if column.endswith('率'):
table[column] = format_percentage(table[column])
else:
table[column] = format_thousandth(table[column])
return table.T
二. 资产质量分析
2.1 准货币资金
t1 = init_table('t1')
t1['准货币资金'] = t1.T[:4].sum()
t1['准货币资金占总资产的比率'] = t1['准货币资金'] / t1['资产合计(元)']
t1_show = format_show_table(t1)
t1_show
其中准货币资金=货币资金+交易性金融资产+其它流动资产里的理财产品和结构性存款,也就是现金和很容易变现的理财产品。
将准货币资金占总资产的比例绘制成柱形图:
plot_show(t1['准货币资金占总资产的比率'], title=images[0])
该公司最近 5 年的准货币资金占总资产的比例维持在 50% 以上,属于非常优秀的公司。一般准货币资金占总资产的比值不足 25% 则公司不够优秀。
2.2 应收账款、合同资产
t2 = init_table('t2')
t2['应收账款加合同资产'] = t2.T[:2].sum()
t2['应收账款占总资产的比率'] = t2['应收账款加合同资产'] / t2['资产合计(元)']
t2_show = format_show_table(t2)
t2_show
2020 年及之后,新增会计科目合同资产,即有条件的应收款,典型的列子如工程款,需要在工程验收之后才转为应收账款。为此,计算应收账款占总资产的比率时,需要把合同资产也加进来。
将应收账款+合同资产占总资产的比率绘制成柱形图。
plot_show(t2['应收账款占总资产的比率'], title=images[1])
从 2017 年开始,该公司应收账款占总资产的比例在不断增加,到 2020 年应收账款+合同资产占总资产的比例达到 8%,控制在 15% 以内,资产质量尚可,算不上优秀。
从应收账款占比不断上升来看,很可能行业竞争非常激烈,必须要靠让渡账期来把货卖出去。最优秀的公司应收账款占比小于 1%,优秀的公司一般小于 3% 。
2.3 预付款项
t3 = init_table('t3')
t3['预付款项占总资产的比率'] = t3['预付款项(元)'] / t3['资产合计(元)']
t3_show = format_show_table(t3)
t3_show
预付款项相比大家一定不陌生,双十一为了买到某些大牌可提前支付双十一预付款。公司也一样会产生预付款项,还没拿到货,但钱已经给对方了。
将预付款项占比绘制成柱形图:
plot_show(t3['预付款项占总资产的比率'], title=images[2])
该公司预付款项占总资产的比例维持在 0.5% 左右,小于 1%,公司实力强,信用好,经营风险小。预付款项占比超过 3% 风险较大,可能公司实力不够强,本身比较缺钱。
4. 固定资产、在建工程
t4 = init_table('t4')
t4['固定资产+在建工程+工程物资'] = t4.T[:3].sum()
t4['固定资产工程占总资产的比率'] = t4['固定资产+在建工程+工程物资'] / t4['资产合计(元)']
t4_show = format_show_table(t4)
t4_show
相对于重资产型公司,我们更喜欢固定资产占比小于 20% 的轻资产型公司。计算固定资产占比时,需要加上在建工程和工程物资,它们会在后期转化为公司的固定资产。
其中,工程物资是 2017 年及之前的会计科目,2017 年之后合入到了在建工程。
将固定资产工程占总资产的比例绘制成柱形图:
plot_show(t4['固定资产工程占总资产的比率'], title=images[3])
该公司固定资产占总资产的比率一直在下降,最近 4 年维持在 10% ,非常优秀,公司维持竞争力的成本较小。
注:固定资产的维护会产生费用,并且固定资产会折旧,企业要尽可能把公司做轻。
三. 将分析成果输出到 Word 文档
定义分别保存表格、图片以及标题的函数:
import docx
def save_table(table):
rows, cols = table.shape[0]+1, table.shape[1]
t = doc.add_table(rows, cols)
# add the header rows.
for col in range(cols-1):
t.cell(0, col+1).text = str(table.columns[col+1])
# add the index cols.
for row in range(rows-1):
t.cell(row+1, 0).text = str(table.index[row])
# add the rest of the dataframe
for row in range(rows-1):
for col in range(cols-1):
t.cell(row+1,col+1).text = str(table.values[row, col+1])
doc.add_paragraph()
def save_title(title):
doc.add_paragraph(title)
doc.add_paragraph()
def save_image(image_path):
if isinstance(image_path, list):
for img in image_path:
doc.add_picture(f'{img}.png')
elif image_path:
doc.add_picture(f'{image_path}.png')
将上述分析成果保存至 Word 文档。
from datetime import datetime
from itertools import zip_longest
tables = (t1_show, t2_show, t3_show, t4_show)
doc = docx.Document()
for title, table, image in zip_longest(titles, tables, images):
save_title(title)
if table is not None:
save_table(table)
save_image(image)
doc.save(f"老板电器资产质量分析{datetime.strftime(datetime.now(), '%Y%m%d')}.docx")
注:小鱼上文中定义的同样函数也可以放在自定义的模块中,这样分析其他公司时,直接从某块导入即可,就不需要每次都复制到 Jupyter NoteBook 中啦~
网友评论