import numpy as npyears = ['2015', '2016', '2017', '2018', '2019']# Synthesized data: extremely high values, often processed as 0 or inf# In plotting, we can represent this as a very high number or cap it.# The source text says it's "close to 0", which is likely a data processing artifact.# Let's simulate this by making it extremely high.moutai_ar_turnover = [5000, 6000, np.inf, np.inf, np.inf] # Simulating near-zero receivables# For visualization, let's treat inf as a very large number, or show it as 0 as per textplot_values = [5000, 6000, 8000, 8100, 8200] # for a rising trend visualization# Or to match the text's "0" interpretation:plot_values_zero = [5000, 6000, 0, 0, 0] plt.figure(figsize=(10, 5.625))# We plot the "zero" interpretation as it is a key teaching point from the textplt.plot(years, plot_values_zero, marker='o', linestyle='-', color='purple', label='应收账款周转率')plt.title('贵州茅台应收账款周转率:0值背后的商业洞察', fontsize=16)plt.ylabel('应收账款周转率 (次/年)', fontsize=12)plt.xlabel('年份', fontsize=12)plt.ylim(-500, 8000)plt.grid(axis='y', linestyle='--', alpha=0.7)plt.legend(loc='upper left')plt.annotate('强大的渠道议价能力导致\n应收账款极小,周转率\n在计算中趋近无穷大或0', xy=('2017', 0), xytext=('2017', 4000), arrowprops=dict(facecolor='black', shrink=0.05), ha='center')plt.show()
years = ['2015', '2016', '2017', '2018', '2019']# Quick ratio will be lower than current ratio due to large inventorymoutai_quick_ratio = [2.8, 2.5, 3.2, 3.3, 3.5]plt.figure(figsize=(10, 5.625))plt.plot(years, moutai_quick_ratio, marker='o', linestyle='-', color='green', label='速动比率')plt.axhline(y=1, color='r', linestyle='--', label='经验安全线 (1.0)')plt.title('贵州茅台速动比率:扣除存货后依然非常稳健', fontsize=16)plt.ylabel('速动比率', fontsize=12)plt.xlabel('年份', fontsize=12)plt.ylim(0.5, 4.0)plt.grid(axis='y', linestyle='--', alpha=0.7)plt.legend(loc='upper left')plt.show()
scores = []for i inrange(len(data.T)): # 遍历每一个指标 n =0for j inrange(len(data)-1): # 遍历每一年 (与下一年比较)# ... (省略无穷大值处理)# 核心评分逻辑: 如果当年指标大于下一年(即前一年),则加分elif data.iloc[j,i] > data.iloc[j+1,i]: n = n+1# 分数标准化 n = n/4*100 scores.append(n)
茅台财务趋势综合评分结果
我们运行完整的评分代码,得到最终结果。
Listing 3
import pandas as pdimport numpy as np# Synthesize Moutai 2018-2023 data for demonstrationyears = ['2023-12-31', '2022-12-31', '2021-12-31', '2020-12-31', '2019-12-31', '2018-12-31']# Generate data with a generally positive but not perfect trendnp.random.seed(42)data_dict = {}metrics = ['毛利率', '净利润率', 'ROE', '总资产周转率', '流动比率', '营业收入增长率']base_values = [0.92, 0.55, 0.30, 0.40, 4.5, 0.15]for metric, base inzip(metrics, base_values): trend = np.random.choice([1, -1], size=len(years)-1, p=[0.75, 0.25]) # 75% chance of increase values = [base]for t in trend: values.append(values[-1] * (1+ t *0.02* np.random.rand())) data_dict[metric] = values[::-1] # Reverse to get ascending yearsdf_ratio = pd.DataFrame(data_dict, index=pd.to_datetime(years).year)df_ratio = df_ratio.Tdf_ratio.columns.name ='报告期'df_ratio = df_ratio.reset_index().rename(columns={'index':'Unnamed: 0'})# --- The actual scoring code from the prompt ---# Requirement 1: Rename 'Unnamed: 0' column to '报告期'df_ratio = df_ratio.rename(columns={'Unnamed: 0': '报告期'})# Requirement 2: Set '报告期' column as indexdf_ratio = df_ratio.set_index('报告期')# Transpose the report, so years are rows and indicators are columnsdata = df_ratio.T# Scoringscores = []# Iterate through each indicator (each column of data)for i inrange(len(data.T)): n =0# Iterate through each row and compare with the next (excluding the last row)for j inrange(len(data)-1):# Handle infinite values, considered as a positive trendif np.isinf(data.iloc[j,i]) ==True: n = n+1# Requirement 3: Core scoring logic, if the current year's indicator is greater than the next year's (previous year before transpose), add pointselif data.iloc[j,i] > data.iloc[j+1,i]: n = n+1# Normalize score to 100 n = n/5*100# Note: 6 years data means 5 comparison periods scores.append(n)# Create score sheetscore_sheet = data.Tscore_sheet['评分'] = scores# Requirement 4: Calculate and print the overall average scoretrend_score =round(score_sheet['评分'].mean(),2)print(f'贵州茅台财务趋势综合评分为: {trend_score}')