Python实现财富分配模拟(如何面对这个残酷的世界?)

目录

引言

模型一:基础财富分配模型

模型二:富二代和普通人有什么区别?

模型三:对富人征税会改变财富分布吗?

模型四:努力的人生会更好吗?

致谢


引言

        财富,在我们的生活中有着重要的地位,古时便以贝壳为货币,而后又以金银代之,直至今日,形形色色的货币流通于市场之间,依然推动着经济的发展。那么如何才能拥有更多的财富?财富流转的规律又是什么?这似乎是成功学研究的问题,毕竟程序代码是不会教我们投资的,但我们可以通过一些简单的数据分析来对财富的分配进行模拟,进而试着找寻一些财富的规律。

        知乎上有一个有趣的财富分配游戏:房间里有100个人,每个人有100元钱,每个人每天都要拿出一元钱随机给另一个人,每个人从18岁开始游戏,一直玩到65岁退休,在约为17000天的游戏过程中,财富会如何变化?

        我们就以这个游戏为蓝本,对四种不同的游戏规则进行模拟,运用python语言编写代码,将每个人的财富值变化用柱状图表现出来,形成如下四个模型:

模型一:基础财富分配模型

        在基础财富分配模型中,每个人有100元钱起始资金,当某人财富值为0时,他在该轮游戏中无需拿出一元钱给别人,但是仍然有机会得到别人给出的钱。

        程序代码如下:

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

#每个人的编号
x = [i for i in range(1,101)]
#模拟社会财富分配,初始财富分配,每人100元
people = pd.DataFrame([100 for i in range(100)],index = x)

#分配算法 
def distribute(data,roundi):
    #存储破产总人数
    poor = 0
    #初始金钱和损失
    round = pd.DataFrame({'pre_round':data[roundi-1],'lost':1})
    #金钱为0时不再扣钱
    for i in range(1,101):
        if round['pre_round'].loc[i] <= 0:
            round['lost'].loc[i] = 0
            poor = poor + 1
    #挑选需要收钱的人
    choice = pd.Series(np.random.choice(x,100-poor))
    #统计收钱的人各自出现的次数(即会收到多少钱)
    gain = pd.DataFrame({'gain':choice.value_counts()})
    #更新round
    round = round.join(gain)
    #将缺省值补为0
    round.fillna(0,inplace = True)
    #返回本轮结束后每个人的金钱状况
    print(round)
    return round['pre_round'] - round['lost'] + round['gain']

fig, ax = plt.subplots()
for i in range(17000):
    #从18岁开始一直到65岁退休,每天进行一次资金流动
    people[i+1] = distribute(people,i+1)
    ax.cla()  # 清除键
    plt.title('Round%d'%(i+1))
    plt.xlabel('Player ID')
    plt.ylabel('Fortune')
    datai = pd.DataFrame({'money':people.T.iloc[i],'color':'green'})
    datai = datai.sort_values(by = 'money')#若需要排序,可将此注释去掉.reset_index()
    ax.bar(datai.index, datai['money'],color = datai['color'], width=0.5)
    ax.legend()
    plt.pause(0.001)
plt.pause(600)

        游戏开始前每个人的财富状态如下图所示:

        

        17000轮游戏后每个人的财富状态如下图所示:

        通过游戏前后柱形图的对比不难发现,在初始条件完全相同的情况下,人与人之间的财富值是会产生差距的,且随着时间的流逝,这样的差距越来越大,最富有的人甚至将自己的财富翻了四倍,囊中羞涩之人更是不在少数。

模型二:富二代和普通人有什么区别?

       然而在真实的社会中,每个人的出身是不同的,有含着金钥匙出生的富二代、星二代,也有过着家徒四壁、箪瓢屡空的生活的贫苦之人。正是基于这样真实情况的考虑,我们从100个人中挑选10人作为富二代,他们将拥有500元的启始资金,且获得财富的概率是普通人的2倍,但是他们每一轮也将拿出2倍的钱。另外需要注意的是,在这个模型中不再对破产提供保护,也就是说如果某人花光了钱,他将通过借贷的方式继续游戏,在柱形图上表现为负值。

        程序代码如下:

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

#每个人的编号
x = [i for i in range(1,101)]
#模拟社会财富分配,初始财富分配,富人每人500元,穷人每人100元
people = pd.DataFrame([100 for i in range(100)],index = x)
for i in [1,11,21,31,41,51,61,71,81,91]:
    people.T[i] = 500
#其他人的概率
p= [1/110 for i in range(100)]
#富人的概率
for i in [1,11,21,31,41,51,61,71,81,91]:
    p[i-1] = 2/110

#分配算法 
def distribute(data,roundi):
    #初始金钱和损失
    round = pd.DataFrame({'pre_round':data[roundi-1],'lost':1})
    #富人需要付出穷人二倍的金钱
    round['lost'].loc[1,11,21,31,41,51,61,71,81,91] = 2
    #挑选需要收钱的人
    choice = pd.Series(np.random.choice(x,110,p = p))
    #统计收钱的人各自出现的次数(即会收到多少钱)
    gain = pd.DataFrame({'gain':choice.value_counts()})
    #更新round
    round = round.join(gain)
    #将缺省值补为0
    round.fillna(0,inplace = True)
    #返回本轮结束后每个人的金钱状况
    return round['pre_round'] - round['lost'] + round['gain']

fig, ax = plt.subplots()
for i in range(17000):
    #从18岁开始一直到65岁退休,每天进行一次资金流动
    people[i+1] = distribute(people,i+1)
    ax.cla()  # 清除键
    plt.title('Round%d'%(i+1))
    plt.xlabel('Player ID')
    plt.ylabel('Fortune')
    datai = pd.DataFrame({'money':people.T.iloc[i],'color':'green'})
    datai['color'].loc[[1,11,21,31,41,51,61,71,81,91]] = 'red'
    datai = datai.sort_values(by = 'money').reset_index()
    ax.bar(datai.index, datai['money'],color = datai['color'], width=0.5)
    ax.legend()
    plt.pause(0.001)
plt.pause(600)

        游戏开始前每个人的财富状态如下图所示:

         17000轮游戏后每个人的财富状态如下图所示:

        在有富二代的模型中我们可以发现:富二代中虽然也有败家子,但他们仍有很大概率将财富值维持在较高水平。富二代和普通人生活在两个世界中,偶有交集而已,而普通人则需要有极好的运气才能达到与富二代相同的高度。

模型三:对富人征税会改变财富分布吗?

        那么有什么办法能够减少贫富差距呢?或者说,有什么办法让不同出身的人有相对平等的致富的机会呢?有人提出:对于富有的人可以限制他们的收入,也就是“收税”;对于贫穷的人可以给予他们帮助,也就是“低保”。在真实的社会中确实有这样的举措,但是这样的措施是否有效呢?我们将在这个模型中给出答案。

        这一次我们依然给每个人100元钱的初始资金,每轮游戏中每个人获得一元钱的概率也相等,但是若被选中的玩家在该轮游戏时的财富值超出200元,则他只能获得60%的收益;而另外40%的收益将平分给财富值低于0元的所有玩家,这正对应着“税收”和“低保”。

        程序代码如下:

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

#每个人的编号
x = [i for i in range(1,101)]
#模拟社会财富分配,初始财富分配,每人100元
people = pd.DataFrame([100 for i in range(100)],index = x)

#分配算法 
def distribute(data,roundi):
    #S保存税收总数
    S = 0
    #poor保存破产的总人数
    poor = 0
    #初始金钱和损失
    round = pd.DataFrame({'pre_round':data[roundi-1],'lost':1})
    #计算破产的人数
    for i in range(1,101):
        if round['pre_round'].loc[i] < 0:
            poor = poor + 1
    #挑选需要收钱的人
    choice = pd.Series(np.random.choice(x,100))
    #统计收钱的人各自出现的次数(即会收到多少钱)
    gain = pd.DataFrame({'gain':choice.value_counts()})
    #更新round
    round = round.join(gain)
    #将缺省值补为0
    round.fillna(0,inplace = True)
    #若财富值大于200,则只获得60%的收益,即交40%的税
    for i in range(1,101):
        if round['pre_round'].loc[i] > 200:
            S = S + round['gain'].loc[i]*0.4
            round['gain'].loc[i] = round['gain'].loc[i]*0.6
    #给穷人发钱
    for i in range(1,101):
        if round['pre_round'].loc[i] < 0:
            round['gain'].loc[i] = round['gain'].loc[i] + S/poor
    #返回本轮结束后每个人的金钱状况
    return round['pre_round'] - round['lost'] + round['gain']

fig, ax = plt.subplots()
for i in range(17000):
    #从18岁开始一直到65岁退休,每天进行一次资金流动
    people[i+1] = distribute(people,i+1)
    ax.cla()  # 清除键
    plt.title('Round%d'%(i+1))
    plt.xlabel('Player ID')
    plt.ylabel('Fortune')
    datai = pd.DataFrame({'money':people.T.iloc[i],'color':'green'})
    datai = datai.sort_values(by = 'money').reset_index()
    ax.bar(datai.index, datai['money'],color = datai['color'], width=0.5)
    ax.legend()
    plt.pause(0.001)
plt.pause(600)

        游戏开始前每个人的财富状态如下图所示:

        17000轮游戏后每个人的财富状态如下图所示:

        在“低保”和“税收”的规则下,社会财富分布仍然是高度极化的,区别只是减少了破产者,且富有的人没有那么富了而已。收税可以延缓世界的分化,但是并不会改变世界的残酷本质。

模型四:努力的人生会更好吗?

        除了政府施加的“税收”和“低保”等干预方式外,还有其他的方式增加我们的财富吗?答案是肯定的。我们还可以通过自己的努力致富,在这个模型中我们就来看一看努力的人是否为自己赢得了更多的财富?
        这一次每个人的初始资金仍然是100元钱,在100人中选取10人作为“更努力的人”,他们比普通人获得钱的概率多1%。

        程序代码如下:

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

#每个人的编号
x = [i for i in range(1,101)]
#模拟社会财富分配,初始财富分配,每人100元
people = pd.DataFrame([100 for i in range(100)],index = x)
#其他人的概率
p= [0.899/90 for i in range(100)]
#努力的人的概率
for i in [1,11,21,31,41,51,61,71,81,91]:
    p[i-1] = 0.0101

#分配算法 
def distribute(data,roundi):
    #初始金钱和损失
    round = pd.DataFrame({'pre_round':data[roundi-1],'lost':1})
    #挑选需要收钱的人
    choice = pd.Series(np.random.choice(x,100,p = p))
    #统计收钱的人各自出现的次数(即会收到多少钱)
    gain = pd.DataFrame({'gain':choice.value_counts()})
    #更新round
    round = round.join(gain)
    #将缺省值补为0
    round.fillna(0,inplace = True)
    #返回本轮结束后每个人的金钱状况
    return round['pre_round'] - round['lost'] + round['gain']

fig, ax = plt.subplots()
for i in range(17000):
    #从18岁开始一直到65岁退休,每天进行一次资金流动
    people[i+1] = distribute(people,i+1)
    ax.cla()  # 清除键
    plt.title('Round%d'%(i+1))
    plt.xlabel('Player ID')
    plt.ylabel('Fortune')
    datai = pd.DataFrame({'money':people.T.iloc[i],'color':'green'})
    datai['color'].loc[1,11,21,31,41,51,61,71,81,91] = 'red'
    datai = datai.sort_values(by = 'money').reset_index()
    ax.bar(datai.index, datai['money'],color = datai['color'], width=0.5)
    ax.legend()
    plt.pause(0.001)
plt.pause(600)

        游戏开始前每个人的财富状态如下图所示:

         17000轮游戏后每个人的财富状态如下图所示:

        可以看到,社会财富的总体分布虽然没有什么变化。但是10位努力的玩家大多进入了富人的行列,尽管最成功的玩家不一定是最努力的那个,但是努力的人大多都混得不错。感谢这个残酷的世界还给我们留下了一条生路。

        那么,该如何面对这个残酷的世界?

        努力,并坚持下去!

致谢

        感谢Nancy对代码编写提供的帮助;

        感谢CRY对模型一数据测试提供的帮助;

        感谢laobaicai对模型二数据测试提供的帮助;

        感谢angrysnowman对模型三数据测试提供的帮助;

        感谢Auswitz对模型四数据测试提供的帮助。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

交交的土拨鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值