Search

Travel Tips

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Lifestyle

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Hotel Review

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Python数据分析实战——社会财富分配问题模拟一

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()

image.png

 模拟第一轮游戏分配

# 考虑情况:当某人的财富值降到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()

image.png

构建函数模型

# 这里注意:当某人的财富值降到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!')

image.png

运行模型,模拟财富分配


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条数据

image.png

绘制柱状图

# ** 前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!')

image.png

image.png

image.png

image.png

image.png

绘制柱状图

# ** 前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!')

image.png

image.png

image.png

image.png

image.png

# 一些结论


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元以下了?


image.png

这是一个简介
    互联网冲浪金牌选手。赖床世锦赛纪录保持者,拖延俱乐部顶级VIP,夜宵外卖一级鉴赏师,国家脱单脱贫重点扶持对象,中央戏精学院优秀学生,亚洲酸柠檬推广大使,国家一级退堂鼓表演艺术家。
评论 (125)
评论

我是 s enim interduante quis metus. Duis porta ornare nulla ut bibendum

Rosie

6 minutes ago

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

Agatha Christie

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

Steven

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.

Danielle Steel

December 4, 2020 at 3:12 pm