社会财富分配问题模拟

【项目13】 社会财富分配问题模拟

PS:如果各位有疑问的话,可以留下微信,我看到会第一时间加的,以后可以多多交流

一个财富分配游戏:
房间里有100个人,每人都有100元钱,他们在玩一个游戏。每轮游戏中,每个人都要拿出一元钱随机给另一个人,最后这100个人的财富分布是怎样的?

1、项目需求

研究问题:
1、财富分配模型
模型假设:
① 每个人初始基金100元
② 从18岁到65岁,每天玩一次,简化运算按照一共玩17000轮
③ 每天拿出一元钱,并且随机分配给另一个人
④ 当某人的财富值降到0元时,他在该轮无需拿出1元钱给别人,但仍然有机会得到别人给出的钱

2、在允许借贷情况下,研究以下问题
和初始模型的区别:
允许借贷意味着可以找亲友、银行、投资人借贷 → 资产为负时,仍然参与游戏

3、努力的人生会更好吗?
模型假设:
① 每个人初始基金仍为100元
② 一共玩17000轮
③ 每天拿出一元钱,并且随机分配给另一个人
④ 有10个人加倍努力,从而获得了1%的竞争优势
⑤ 允许借贷
允许借贷意味着可以找亲友、银行、投资人借贷 → 资产为负时,仍然参与游戏

2、实过程

1、导入模块

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import time

import warnings
warnings.filterwarnings("ignore")
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
plt.style.use('classic')
os.chdir('C:\\Users\\Administrator\\Desktop')

2、创建初始数据,模拟不借贷模型

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'

#设置第一次交易,没有为0的数值
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()})
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']

#设置第一次交易,假设有为0的数值为0的数值
round_r1 = pd.DataFrame({'pre_round':fortune[0],'lost':0})
round_r1['lost'][round_r1['pre_round']>0] = 1
round_players = round_r1[round_r1['lost']>0]
choice_r1 = pd.Series(np.random.choice(person_n,len(round_players)))
gain_r1 = pd.DataFrame({'gain':choice_r1.value_counts()})
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']


#问题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'
#问题1:设置无法借贷模型
def data1(data,roundi):
    if len(data[data[roundi - 1]==0])>0:
        round_i = pd.DataFrame({'pre_round':data[roundi-1],'lost':0})
        con = round_i['pre_round']>0
        round_i['lost'][con] = 1
        round_playeri = round_i[con]
        choice_i = pd.Series(np.random.choice(person_n,len(round_playeri)))
        gain_i = pd.DataFrame({'gain':choice_i.value_counts()})
        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:
        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()})
        round_i = round_i.join(gain_i)
        round_i.fillna(0,inplace = True)
        return round_i['pre_round'] - round_i['lost'] + round_i['gain']
#问题1:运行模型
startime = time.time()
for i in range(1,17001):
    fortune[i] = data1(fortune,i)
    endtime = time.time()
    print('第%i个数据已用时%.3f秒'%(i,(endtime-startime)))
q1 = fortune.T
endtime = time.time()
print('总用时%.3f秒'%(endtime-startime))  

#问题1:绘制柱状图
def fig1(data,start,end,i):
    for j in range(start,end,i):
        datai = data.iloc[j]
        plt.figure(figsize = (15,5))
        plt.bar(datai.index,datai.values,
                color = 'k',alpha = 0.6,width = 0.8)
        plt.title('Round%i'%j)
        plt.grid()
        plt.xlim([-10,110])
        plt.ylim([0,500])
        plt.savefig('C:\\Users\\Administrator\\Desktop\\交易图例\\不排序\\第%i轮交易图'%j,dip = 500)
f2(q1,0,101,10)
f2(q1,100,1001,100)
f2(q1,1000,17001,400)

输出17000轮后数据

在这里插入图片描述
3、绘制排序的非借贷柱状图

def fig1_sort(data,start,end,i):
    for j in range(start,end,i):
        datai = data.iloc[j]
        datai = datai.sort_values().reset_index()[j]
        plt.figure(figsize = (15,5))
        plt.bar(datai.index,datai.values,
                color = 'k',alpha = 0.6,width = 0.8)
        plt.title('Round%i'%j)
        plt.grid()
        plt.xlim([-10,110])
        plt.ylim([0,500])
        plt.savefig('C:\\Users\\Administrator\\Desktop\\交易图例\\排序\\第%i轮排序交易图'%j,dip = 500)
fig1_sort(q1,0,101,10)
fig1_sort(q1,100,1001,100)
fig1_sort(q1,1000,17001,400)

#问题1:得出结论
round_end1 = q1.iloc[17000].sort_values(ascending = False).reset_index()
round_end1['fortune'] = round_end1[17000]/100
round_end1['sum_pre'] = round_end1[17000]/round_end1[17000].sum()
round_end1['cumsum_pre'] = round_end1['sum_pre'].cumsum()
round_end1.columns = ['id','money','fortune_bs','sum_pre','cumsum_pre']

在这里插入图片描述

结论:财富随机分配之后财富最终变为指数分布

4、设置可借贷模型并绘制最终借贷后分布图

#问题2:设置基础数据
person_n = [x for x in range(1,101)]
fortune2 = pd.DataFrame([100 for i in range(100)],index = person_n)
fortune2.index.name = 'id'

#问题2:设置可借贷模型
def data2(data,roundi):
    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()})
    round_i = round_i.join(gain_i)
    round_i.fillna(0,inplace = True)
    return round_i['pre_round'] - round_i['lost'] + round_i['gain']
startime2 = time.time()
for i in range(1,17001):
    fortune2[i] = data2(fortune2,i)
    endtime2 = time.time()
    print('第%i个数据已用时%.3f秒'%(i,(endtime2-startime2)))
q2 = fortune2.T
endtime = time.time()
print('总用时%.3f秒'%(endtime2-startime2))  

#问题2:得出问题2破产id
std_q2 = fortune2.std()
plt.figure(figsize = (15,6))
std_q2.plot(kind = 'line',color = 'r',grid = True,title = '每轮财富标准差')
pc_id = q2.iloc[6200]
pc_id = pc_id[pc_id<0].index.tolist()
print('破产id为%r'% pc_id)


#问题2:绘图查看
def fig2(data,start,end,i):
    for j in range(start,end,i):
        datai = data.iloc[j]
        datai = datai.sort_values().reset_index()[j]
        plt.figure(figsize = (15,5))
        plt.bar(datai.index,datai.values,
                color = 'k',alpha = 0.6,width = 0.8)
        plt.title('Round%i'%j)
        plt.grid()
        plt.xlim([-10,110])
        plt.ylim([-300,600])
        plt.savefig('C:\\Users\\Administrator\\Desktop\\交易图例\\借贷排序\\第%i轮排序交易图'%j,dip = 500)
fig2(q2,0,101,10)
fig2(q2,100,1001,100)
fig2(q2,1000,17001,400)

在这里插入图片描述
结论:允许借贷之后有钱的更有钱了,没钱的就更没钱了

5、筛选35岁财富为0以下id,查看到70岁是否逆袭的情况

#问题2:绘图查看已经破产的能否逆袭
def fig2_nx(data,start,end,i):
    for j in range(start,end,i):
        datai = pd.DataFrame({'money':q2.iloc[j],'color':'k'})
        datai['color'].loc[pc_id] = 'r'
        datai = datai.sort_values('money').reset_index()
        plt.figure(figsize = (15,5))
        plt.bar(datai.index,datai['money'],
                color = datai['color'],alpha = 0.6,width = 0.8)
        plt.title('Round%i'%j)
        plt.grid()
        plt.xlim([-10,110])
        plt.ylim([-300,600])
        plt.savefig('C:\\Users\\Administrator\\Desktop\\交易图例\\是否逆袭借贷排序\\第%i轮排序交易图'%j,dip = 500)
fig2_nx(q2,6200,17001,500)
print('结论是:如果你35岁破产了,那么很难有机会爬到顶层')

在这里插入图片描述
结论:如果你35岁破产了,那么很难有机会爬到顶层,但是还是有一部分人可以不在处于破产状态。

6、设置基础努力人生数据,创建模型

#问题3:设置基础数据,设置choice的基础概率
person_p3 = [0.899/90 for i in range(100)]
for i in [1,11,21,31,41,51,61,71,81,91]:
    person_p3[i-1] = 0.0101
person_n = [x for x in range(1,101)]
fortune3 = pd.DataFrame([100 for i in range(100)],index = person_n)
fortune3.index.name = 'id'


#问题3:设置模型运行模型
def data3(data,roundi):
    round_i = pd.DataFrame({'pre_round':data[roundi-1],'lost':1})
    choice_i = pd.Series(np.random.choice(person_n,100,p = person_p3))
    gain_i = pd.DataFrame({'gain':choice_i.value_counts()})
    round_i = round_i.join(gain_i)
    round_i.fillna(0,inplace = True)
    return round_i['pre_round'] - round_i['lost'] + round_i['gain']
startime3 = time.time()
for i in range(1,17001):
    fortune3[i] = data3(fortune3,i)
    endtime3 = time.time()
    print('第%i个数据已用时%.3f秒'%(i,(endtime2-startime2)))
q3 = fortune3.T
endtime3 = time.time()


#问题3:绘制初始交易图
data0 = pd.DataFrame({'money':q3.iloc[0],'color':'k'})
data0['color'].loc[[1,11,21,31,41,51,61,71,81,91]] = 'r'
plt.figure(figsize = (15,5))
plt.bar(data0.index,data0['money'],
color = data0['color'],alpha = 0.6,width = 0.8)
plt.title('Round0')
plt.grid()
plt.xlim([-10,110])
plt.ylim([-300,600])
plt.savefig('C:\\Users\\Administrator\\Desktop\\交易图例\\努力的人借贷排序\\第0轮排序交易图',dip = 500)


#问题3:绘制图标查看努力情况
def fig3(data,start,end,i):
    for j in range(start,end,i):
        datai = pd.DataFrame({'money':q3.iloc[j],'color':'k'})
        datai['color'].loc[[1,11,21,31,41,51,61,71,81,91]] = 'r'
        datai = datai.sort_values(by = 'money').reset_index()
        plt.figure(figsize = (15,5))
        plt.bar(datai.index,datai['money'],
                color = datai['color'],alpha = 0.6,width = 0.8)
        plt.title('Round%i'%j)
        plt.grid()
        plt.xlim([-10,110])
        plt.ylim([-300,600])
        plt.savefig('C:\\Users\\Administrator\\Desktop\\交易图例\\努力的人借贷排序\\第%i轮排序交易图'%j,dip = 500)
fig3(q3,10,100,10)
fig3(q3,100,1000,100)
fig3(q3,1000,17000,400)
print('总用时%.3f秒'%(endtime2-startime2))  
print('努力的人更能到达财富的靠前位置')
print('finished')


在这里插入图片描述
结论:努力的人更能到达财富值的金字塔顶端,努力就会有回报

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值