Travel Tips
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Python数据分析实战——社会财富分配问题模拟一
房间里有100个人,每人都有100元钱,他们在玩一个游戏。每轮游戏中,每个人都要拿出一元钱随机给另一个人,最后这100个人的财富分布是怎样的?
import numpy as np import pandas as pd import matplotlib.pyplot as plt import os import warnings warnings.filterwarnings('ignore') # 不发出警告 import time # 导入时间模块 '''
模型假设:
① 每个人初始基金100元
② 从18岁到65岁,每天玩一次,简化运算按照一共玩17000轮
③ 每天拿出一元钱,并且随机分配给另一个人
④ 当某人的财富值降到0元时,他在该轮无需拿出1元钱给别人,但仍然有机会得到别人给出的钱
要求:
① 构建模型模拟(这里需要跑17000轮)
② 绘制柱状图,查看该轮财富情况
** 横轴标签代表一个玩家的编号,柱子的高低变动反映该玩家财富值的变化
** 制图分两个情况绘制:不排序绘制、每轮按照财富值排序绘制
** 前100轮,按照每10轮绘制一次柱状图,查看财富变化情况
** 100至1000轮,按照每100轮绘制一次柱状图,查看财富变化情况
** 1000至17000轮,按照每400轮绘制一次柱状图,查看财富变化情况
③ 查看最后财富分配数据是什么分布?
④ 最富有的人相比于初始财富,翻了多少倍?
⑤ 10%的人掌握着多少的财富?30%的人掌握着多少的财富?又有百分之多少人财富缩水至100元以下了?
提示:
① 首先,模拟第一轮游戏分配,不考虑某人财富值降到0元的情况
② 其次,仍然模拟第一轮游戏分配,但考虑某人的财富值降到0元时的情况
③ 构建模型
④ 运行模型,先试运行100条/1000条,再运行17000
⑤ 制图
'''
# 模型假设:
# ① 每个人初始基金100元
# ② 从18岁到65岁,每天玩一次,简化运算按照一共玩17000天
# ③ 每天拿出一元钱,并且随机分配给另一个人
# ④ 当某人的财富值降到0元时,他在该轮无需拿出1元钱给别人,但仍然有机会得到别人给出的钱
# (1) 模拟第一轮游戏分配
# 先不考虑某人财富值降到0元的情况
person_n = [x for x in range(1,101)] fortune = pd.DataFrame([100 for i in range(100)], index = person_n) fortune.index.name = 'id' # 设定初始参数:游戏玩家100人,起始资金100元 round_r1 = pd.DataFrame({'pre_round':fortune[0],'lost':1}) # 设定第一轮分配财富之前的情况 choice_r1 = pd.Series(np.random.choice(person_n,100)) gain_r1 = pd.DataFrame({'gain':choice_r1.value_counts()}) # 这一轮中每个人随机指定给“谁”1元钱,并汇总这一轮每个人的盈利情况 round_r1 = round_r1.join(gain_r1) round_r1.fillna(0,inplace = True) fortune[1] = round_r1['pre_round'] - round_r1['lost'] + round_r1['gain'] # 合并数据,得到这一轮每个人“盈亏”多少钱 → 得到这一轮财富分配的结果 fortune.head()
# 考虑情况:当某人的财富值降到0元时,他在该轮无需拿出1元钱给别人,但仍然有机会得到别人给出的钱 person_n = [x for x in range(1,101)] fortune = pd.DataFrame([100 for i in range(100)], index = person_n) fortune.index.name = 'id' # 设定初始参数:游戏玩家100人,起始资金100元 round_r1 = pd.DataFrame({'pre_round':fortune[0],'lost':0}) round_r1['lost'][round_r1['pre_round'] > 0] = 1 # 设定第一轮分配财富之前的情况 → 该轮财富值为0的不需要拿钱给别人 round_players = round_r1[round_r1['pre_round'] > 0] # 筛选出参与游戏的玩家:财富值>0 choice_r1 = pd.Series(np.random.choice(person_n,len(round_players))) gain_r1 = pd.DataFrame({'gain':choice_r1.value_counts()}) # 这一轮中每个人随机指定给“谁”1元钱,并汇总这一轮每个人的盈利情况 round_r1 = round_r1.join(gain_r1) round_r1.fillna(0,inplace = True) fortune[1] = round_r1['pre_round'] - round_r1['lost'] + round_r1['gain'] # 合并数据,得到这一轮财富分配的结果 fortune.head()
# 这里注意:当某人的财富值降到0元时,他在该轮无需拿出1元钱给别人,但仍然有机会得到别人给出的钱
def game1(data, roundi): if len(data[data[roundi - 1] ==0]) > 0: # 当数据包含财富值为0的玩家时 round_i = pd.DataFrame({'pre_round':data[roundi-1],'lost':0}) con = round_i['pre_round'] > 0 round_i['lost'][con] = 1 # 设定每轮分配财富之前的情况 → 该轮财富值为0的不需要拿钱给别人 round_players_i = round_i[con] # 筛选出参与游戏的玩家:财富值>0 choice_i = pd.Series(np.random.choice(person_n,len(round_players_i))) gain_i = pd.DataFrame({'gain':choice_i.value_counts()}) # 这一轮中每个人随机指定给“谁”1元钱,并汇总这一轮每个人的盈利情况 round_i = round_i.join(gain_i) round_i.fillna(0,inplace = True) return round_i['pre_round'] - round_i['lost'] + round_i['gain'] # 合并数据,得到这一轮财富分配的结果 else: # 当数据不包含财富值为0的玩家时 round_i = pd.DataFrame({'pre_round':data[roundi-1],'lost':1}) # 设定每轮分配财富之前的情况 choice_i = pd.Series(np.random.choice(person_n,100)) gain_i = pd.DataFrame({'gain':choice_i.value_counts()}) # 这一轮中每个人随机指定给“谁”1元钱,并汇总这一轮每个人的盈利情况 round_i = round_i.join(gain_i) round_i.fillna(0,inplace = True) return round_i['pre_round'] - round_i['lost'] + round_i['gain'] # 合并数据,得到这一轮财富分配的结果 print('finished!')
person_n = [x for x in range(1,101)] fortune = pd.DataFrame([100 for i in range(100)], index = person_n) fortune.index.name = 'id' # 设定初始参数:游戏玩家100人,起始资金100元 starttime = time.time() # 模型开始时间 for round in range(1,17001): fortune[round] = game1(fortune,round) # 进行17000轮随机分配模拟 game1_result = fortune.T # 转置后得到结果数据 → 列为每一个人的id,行为每一轮的财富分配结果 endtime = time.time() # 模型结束时间 print('模型总共用时%i秒' % (endtime - starttime)) # 计算时间 game1_result.tail() # 查看最后5条数据
# ** 前100轮,按照每10轮绘制一次柱状图,查看财富变化情况 # ** 100至1000轮,按照每100轮绘制一次柱状图,查看财富变化情况 # ** 1000至17000轮,按照每400轮绘制一次柱状图,查看财富变化情况 # ① 不排序绘制
os.chdir('/home/zty/Documents/python/Python进阶数据分析及可视化/实战/练习08_社会财富分配问题模拟/财富分配模型_初始模型_不排序绘制') def graph1(data,start,end,length): for n in list(range(start,end,length)): datai = data.iloc[n] plt.figure(figsize = (10,6)) plt.bar(datai.index,datai.values,color='gray',alpha = 0.8,width = 0.9) plt.ylim((0,400)) plt.xlim((-10,110)) plt.title('Round %d' % n) plt.xlabel('PlayerID') plt.ylabel('Fortune') plt.grid(color='gray', linestyle='--', linewidth=0.5) plt.savefig('graph1_round_%d.png' % n, dpi=200) # 创建绘图函数1 graph1(game1_result,0,100,10) graph1(game1_result,100,1000,100) graph1(game1_result,1000,17400,400) print('finished!')
# ** 前100轮,按照每10轮绘制一次柱状图,查看财富变化情况
# ** 100至1000轮,按照每100轮绘制一次柱状图,查看财富变化情况
# ** 1000至17000轮,按照每400轮绘制一次柱状图,查看财富变化情况
# ② 每轮按照财富值排序绘制
os.chdir('/home/zty/Documents/python/Python进阶数据分析及可视化/实战/练习08_社会财富分配问题模拟/财富分配模型_初始模型_排序绘制/') def graph2(data,start,end,length): for n in list(range(start,end,length)): datai = data.iloc[n].sort_values().reset_index()[n] plt.figure(figsize = (10,6)) plt.bar(datai.index,datai.values,color='gray',alpha = 0.8,width = 0.9) plt.ylim((0,400)) plt.xlim((-10,110)) plt.title('Round %d' % n) plt.xlabel('PlayerID') plt.ylabel('Fortune') plt.grid(color='gray', linestyle='--', linewidth=0.5) plt.savefig('graph2_round_%d.png' % n, dpi=200) # 创建绘图函数2 graph2(game1_result,0,100,10) graph2(game1_result,100,1000,100) graph2(game1_result,1000,17400,400) print('finished!')
round_17000_1 = pd.DataFrame({'money':game1_result.iloc[17000]}).sort_values(by = 'money',ascending = False).reset_index() round_17000_1['fortune_pre'] = round_17000_1['money'] / round_17000_1['money'].sum() round_17000_1['fortune_cumsum'] = round_17000_1['fortune_pre'].cumsum() round_17000_1.head() # 最后一轮中,最富有的人财富值为365元,相比于初始财富,翻了3.65倍 # 10%的人掌握着28%的财富,20%的人掌握着51%的财富? # 60%的人财富缩水至100元以下了?
Sed ac lorem felis. Ut in odio lorem. Quisque magna dui, maximus ut commodo sed, vestibulum ac nibh. Aenean a tortor in sem tempus auctor
December 4, 2020 at 3:12 pm
Sed ac lorem felis. Ut in odio lorem. Quisque magna dui, maximus ut commodo sed, vestibulum ac nibh. Aenean a tortor in sem tempus auctor
December 4, 2020 at 3:12 pm
Donec in ullamcorper quam. Aenean vel nibh eu magna gravida fermentum. Praesent eget nisi pulvinar, sollicitudin eros vitae, tristique odio.
December 4, 2020 at 3:12 pm
我是 s enim interduante quis metus. Duis porta ornare nulla ut bibendum
Rosie
6 minutes ago