def parseCSV(filename): #* 解析CSV文件,从中读取数据,并把数据表示为列表类型。
dataNames,data = [],[]
f = open(filename,'r',encoding='utf-8-sig') #! 已事先以记事本方式打开原CSV文件,然后另存为时编码选择UTF-8进行保存
for line in f: #! 或者在原excel文件另存为时,选择CSV UTF-8格式保存
splitedLine = line.strip('\n').split(',')
if '指标' in splitedLine[0]:
years = [int(x[:-1]) for x in splitedLine[1:]] # 去掉指标这一行中的年,变为2000 2015 2016
else:
dataNames.append('{:10}'.format(splitedLine[0])) # 输出每行第一个元素即全部的指标名称
data.append([float(x) for x in splitedLine[1:]]) # 输出每一行的财政数字
f.close()
return years,dataNames,data #分别以列表形式返回年份、指标名称、财政数字。
line1 = "指标,2000年,2015年,2016年" 字符串
line2 = "全部收入,13395.2,152269.2,159605“
splitedLine1 = ["指标","2000年","2015年","2016年"] 一维列表,元素是字符串
splitedLine2 = ["全部收入","13395.2","152269.2","159605“]
years = [2000, 2015, 2016],
dataNames = ['全部收入 ', '中央收入 ', '地方收入 ', '全部支出 ', '中央支出 ', '地方支出 ']
data = [[13395.2, 152269.2, 159605.0], [6989.2, 69267.2, 72365.6], [6406.1, 83002.0, 87239.4], [15886.5, 175877.8, 187755.2],
[5519.9, 25542.2, 27403.9], [10366.7, 150335.6, 160351.4]]
def means(data):
return sum(data)/len(data) #* 计算数据均值,即求x的平均数和y的平均数
def linearRegression(xlist,ylist): #* 求xlist、ylist线性回归值
xmeans,ymeans = means(xlist),means(ylist)
bNumerator = -len(xlist) * means(xlist) * means(ylist) # b分子中的-n*xba*yba
bDenominator = -len(xlist) * means(xlist) ** 2 # b分母中的-n*xba^2
for x,y in zip(xlist,ylist): # zip(): 对xlist和ylist进行同步遍历,每次取出各自一个元素x和y
bNumerator += x * y # 求b的分子 ∑xy - n*xba*yba
bDenominator += x ** 2 # 求b的分母 ∑x^2 - n*xba^2
b = bNumerator/bDenominator
a = ymeans -b * xmeans
return a,b #? 返回一个指标如(全部收入)的回归方程中的常数a、b
注释中xba 代表 ,yba代表
def calNewData(newyears,a,b): #* 计算新年份对应的y值即data值
return [(a + b*x) for x in newyears]
def showResults(years,dataNames,newDatas): #* 集中展示运行结果,重点在于格式化输出
print('{:^60}'.format('国家财政收支线性估计'))
header = '指标 '
for year in years: # 根据main()函数,这时years = newyears = [2010,2011,2012,2013,2014,2015,2016]
header += '{:10}'.format(year)
print(header) #header = 指标 2010 2011 2012 2013 2014 2015 2016
for name,lineData in zip(dataNames,newDatas):
line = name
for data in lineData:
line += '{:>10.1f}'.format(data)
print(line)
zip(dataNames,newDatas) = [(全部收入,[105359.6, 114550.1, 123740.6, 132931.0, 142121.5, 151312.0, 160502.4])
(中央收入,[48169.1, 52283.8, 56398.5, 60513.2, 64627.9, 68742.7, 72857.4])...]
line1 = 全部收入 105359.6 114550.1 123740.6 132931.0 142121.5 151312.0 160502.4
line2 = 中央收入 48169.1 52283.8 56398.5 60513.2 64627.9 68742.7 72857.4
line3 = 地方收入 57190.6 62266.3 67342.1 72417.8 77493.6 82569.3 87645.1
......
def main():
newyears = [x+2010 for x in range(7)] # newyears = [2010,2011,2012,2013,2014,2015,2016]
newDatas = []
years,dataNames,datas = parseCSV('D:/Python/TEXT/Finance.csv') # years = 年份 dataNames = 指标名称 datas = 财政数字
for data in datas:
a,b = linearRegression(years,data) # 调用函数,代入数据,算出各个指标回归方程a、b的值。 years = xlist data = ylist
newDatas.append(calNewData(newyears,a,b)) # 把a、b代入函数calNewData()中,算出新年份对应值 然后再在newDatas空列表中依次加入 a+b*2010、 a+b*2011...等新年份对应值
showResults(newyears,dataNames,newDatas)
years = [2000, 2015, 2016],
dataNames = ['全部收入 ', '中央收入 ', '地方收入 ', '全部支出 ', '中央支出 ', '地方支出 ']
datas = [[13395.2, 152269.2, 159605.0], [6989.2, 69267.2, 72365.6], [6406.1, 83002.0, 87239.4], [15886.5, 175877.8, 187755.2],
[5519.9, 25542.2, 27403.9], [10366.7, 150335.6, 160351.4]]
newDatas = [a+b*2010,a+b*2011,a+b*2012,a+b*2013,a+b*2014,a+b*2015,a+b*2016] --总共有6个不同的a、b值,即有6个回归方程对应6个指标
main()
步骤:
1、parseCSV() 解析CSV文件,分离出年份、指标名称、对应值
2、linearRegression() 利用第一步的年份和对应值,求出6个指标6个回归方程中的a、b值
3、calNewData() 已知newyears = [2010,2011,2012,2013,2014,2015,2016],结合第二步的6个a,b值,求出新年份的对应值newDatas
4、showResults() 排版、格式化输出。重点是利用zip(x,y)函数,交织返回指标名称和newDatas,然后再利用遍历循环和line += data 按行输出。
5、main() 主逻辑部分,预分配列表变量、调用各步骤或各流程函数
注:zip(x,y)函数用来获取两个组合数据类型x和y,并将他们的元素交织返回。例如,x = [1,2,3] y = [4,5,6]
zip(x,y)的返回值是[(1,4),(2,5),(3,6)]