python的盈利模式_穷人和富人就差1%的努力——python模拟社会财富分配游戏

社会资金流是持续而有目的性的,你是否曾想过,为何富人会出现,穷人又为何会出现?穷人和富人究竟如何形成,是否努力就一定能获得成功,赢得更多金钱?今天,让我们用python代码,来模拟一个小社会,看看财富的分配到底是怎样的。

游戏规则:

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

游戏一:没有借贷的社会

1.1 模型假设

每个人初始基金100元

从18岁到65岁,每天玩一次,简化运算按照一共玩17000轮

每天拿出一元钱,并且随机分配给另一个人

当某人的财富值降到0元时,他在该轮无需拿出1元钱给别人,但仍然有机会得到别人给出的钱

游戏一,我们假设分配到财富值为0时可不用出钱,可看做社会前期,没有借贷的日子。

1.2 搭建模型

1.2.1 导入所需函数库

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import os

import time

import warnings

warnings.filterwarnings('ignore')

# 不发出警告

1.2.2 第一轮游戏

第一轮游戏,先不考虑某人财富值会出现0元或以下的情况,这里是100轮内。

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']

# 合并数据,得到这一轮每个人“盈亏”多少钱 → 得到这一轮财富分配的结果

数据展示

1.2.3 第二轮游戏

第二轮游戏,需要考虑当某人财富值降到0元时,他在本轮无需拿出1元,同时可以有机会拿到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']

# 合并数据,得到这一轮财富分配的结果

1.2.4 构建模型

把前两轮游戏汇总成一个函数模型

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']

# 合并数据,得到这一轮财富分配的结果

1.2.5 运行模型

执行代码,获得最终结果

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

# 计算时间

1.3 数据可视化

把模拟结果按财富值升序的顺序作出柱状图,同时输出图片,方便查看。

由于数据每轮变化波动较小,这里

前100轮,每10轮绘制一个图

100-1000轮,每100轮绘制一个图

1000-17000轮,每400轮绘制一个图

os.chdir('C:\\Users\\Hjx\\Desktop\\财富分配游戏一')

def graph1(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('graph1_round_%d.png' % n, dpi=300)

# 创建绘图函数2

graph1(game1_result,0,100,10)

graph1(game1_result,100,1000,100)

graph1(game1_result,1000,17400,400)

print('finished!')

round0-round10600

round17000

从图可知,100人的财富值随游戏回合增加,贫富差距越来越明显。整体指数呈抛物线状,不过差距并不明显。

模拟实验开始前,我也曾以为无论进行多少轮,100人的财富值并无明显差异,毕竟每个人每一轮都必须拿出一元,而得到一元的概率是一样的。然而现实告诉你,富人和穷人就是这样出现的。

1.4 结果分析

对结果进行排序,增加累积和

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

部分数据展示

得出结论:

经过17000轮,最富有的人财富值为404元相比于初始财富,为4.04倍

6%的人掌握着群体约20%的财富,20%的人掌握着群体约50%的财富

60%的人财富减少,低于100元

9%的人财富不到原始财富的10%(即10元以下)

游戏二:允许借贷的社会

2.1 模型假设

每个人初始基金100元

从18岁到65岁,每天玩一次,简化运算按照一共玩17000轮

每天拿出一元钱,并且随机分配给另一个人

当某人的财富值降到0元时,允许财富值为负,即同样需要拿出1元钱给别人,有机会得到别人给出的钱

游戏二,我们允许借贷,当财富值为0时同样需要拿出钱,可以为负值,继续参与游戏。相当于现实世界的向亲友、银行、伙伴借钱,比较符合现今社会。

2.2 搭建模型

2.2.1 构建模型

不同于游戏一,这里可直接考虑为一种情况,不限制拿出收获金钱

def game2(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()}) # 这一轮中每个人随机指定给“谁”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!')

2.2.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'

# 设定初始参数:游戏玩家100人,起始资金100元

starttime = time.time() # 模型开始时间

for round in range(1,17001):

fortune[round] = game2(fortune,round) # 进行17000轮随机分配模拟

game2_result = fortune.T # 转置后得到结果数据 → 列为每一个人的id,行为每一轮的财富分配结果

endtime = time.time() # 模型结束时间

print('模型总共用时%i秒' % (endtime - starttime))

# 计算时间

2.3 数据可视化

round_17000_2 = pd.DataFrame({'money':game2_result.iloc[17000]}).sort_values(by = 'money',ascending = False).reset_index()

round_17000_2['fortune_pre'] = round_17000_2['money'] / round_17000_2['money'].sum()

round_17000_2['fortune_cumsum'] = round_17000_2['fortune_pre'].cumsum()

round_17000_2.head(50)

部分数据展示

2.3.1 财富分布差异随时间的变化趋势

利用以上数据,来看看每个回合财富分布差异的大小

game2_st = game2_result.std(axis = 1)

game2_st.plot(figsize = (12,5),color = 'red',alpha = 0.6,grid = True)

plt.show()

财富标准差与回合数的关系

从图中可以发现,约6000回合前,财富标准差变化极快。而6000回合后,变化趋于稳定,在一定斜率上波动。

就于我们的游戏规则,可以得出财富值在每个人35岁左右已形成明显差异。35岁可以大致判定一个人是否事业有成。

2.3.2 “35岁”暂时失利,能否实现逆袭

游戏群体从18岁开始,为方便计算35岁的失利人群能否逆袭,18-35岁大致为6200个回合。

这里我们定义暂时失利的人群为6200回合后,财富值为负的人,看看此后他们能否逆袭(由负变正)

game2_round6200 = pd.DataFrame({'money':game2_result.iloc[6200].sort_values().reset_index()[6200],

'id':game2_result.iloc[6200].sort_values().reset_index()['id'],

'color':'gray'})

game2_round6200['color'][game2_round6200['money'] < 0] = 'red'

id_pc = game2_round6200['id'][game2_round6200['money'] < 0].tolist()

print('财富值为负的玩家id为:\n',id_pc)

# 筛选数据

# 设置颜色参数

plt.figure(figsize = (10,6))

plt.bar(game2_round6200.index,game2_round6200['money'],color = game2_round6200['color'],alpha = 0.8,width = 0.9)

plt.grid(color='gray', linestyle='--', linewidth=0.5)

plt.ylim((-200,400))

plt.xlim((-10,110))

plt.title('Round 6200')

plt.xlabel('PlayerID')

plt.ylabel('Fortune')

plt.show()

失利人群

接下来,我们查看他们6200-17000回合后的财富值变化情况

os.chdir('C:\\Users\\QJ\\Desktop\\项目13\\game2')

def graph2(data,start,end,length):

for n in list(range(start,end,length)):

datai = pd.DataFrame({'money':data.iloc[n],'color':'gray'})

datai['color'].loc[id_pc] = 'red'

datai = datai.sort_values(by = 'money').reset_index()

plt.figure(figsize = (10,6))

plt.bar(datai.index,datai['money'],color=datai['color'],alpha = 0.8,width = 0.9)

plt.grid(color='gray', linestyle='--', linewidth=0.5)

plt.ylim((-200,400))

plt.xlim((-10,110))

plt.title('Round %d' % n)

plt.xlabel('PlayerID')

plt.ylabel('Fortune')

plt.savefig('graph2_round_%d.png' % n, dpi=200)

graph2(game2_result,6200,17000,500)

print('finished!')

35岁

42岁

49岁

64岁

最终,10人只有3人能逆袭成功。当中我们可以发现在在42岁,有4人逆袭且财富值能位列40名前后。然而在社会资金流运转下,最终只有3人逆袭,且财富值均属于超低水平。

2.4 结果分析

返回到游戏二整体数据,得出结论:

经过17000轮,最富有的人财富值为498元相比于初始财富,为4.98倍

5%的人掌握着群体约20%的财富,15%的人掌握着群体约50%的财富

53%的人财富减少,低于100元

25%的人破产,财富值为负数

对比游戏一和游戏二,我们可以发现,在允许借贷的条件下

最富有的人财富值容易更高

社会总资金更集中于少数人手里

贫富差距增大,破产人群数量大

回归现实

破产人群并没有模拟实验的数字那么吓人,这是由于收入支出的不对等和社会福利的影响。

发现没有,模拟实验把每个人的收入支出几率对等化,然而现实并不会出现每个个体一样的工作待遇和消费支出,所以现实模型来得更为复杂多变。

为了继续游戏,对应现实,我们假设有10个人勤奋努力,获得1%的竞争优势,看看财富分配又会出现怎样的变化。

游戏三:努力就一定有回报?

3.1 模型假设

每个人初始基金100元

从18岁到65岁,每天玩一次,简化运算按照一共玩17000轮

每天拿出一元钱,并且随机分配给另一个人

当某人的财富值降到0元时,允许财富值为负,即同样需要拿出1元钱给别人,有机会得到别人给出的钱

其中,有10人勤奋努力,获得1%的竞争优势(即每轮有0.0101的概率拿到1元,其他人则为0.899/90)

3.2 搭建模型

3.2.1 构建模型

这里,设置努力的10个人id 分别为:[1,11,21,31,41,51,61,71,81,91],方便后续跟踪观察。

person_p = [0.899/90 for i in range(100)]

for i in [1,11,21,31,41,51,61,71,81,91]:

person_p[i-1] = 0.0101

# 设置概率

def game3(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_p))

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] = game3(fortune,round) # 进行17000轮随机分配模拟

game3_result = fortune.T # 转置后得到结果数据 → 列为每一个人的id,行为每一轮的财富分配结果

endtime = time.time() # 模型结束时间

print('模型总共用时%i秒' % (endtime - starttime))

# 计算时间

数据展示

3.3 数据可视化

os.chdir('C:\\Users\\QJ\\Desktop\\项目13\\game3')

plt.figure(figsize = (10,6))

data0 = pd.DataFrame({'money':game3_result.iloc[0],'color':'gray'})

data0['color'].loc[[1,11,21,31,41,51,61,71,81,91]] = 'red'

plt.bar(data0.index,data0['money'],color=data0['color'],alpha = 0.8,width = 0.9)

plt.grid(color='gray', linestyle='--', linewidth=0.5)

plt.ylim((-200,400))

plt.xlim((-10,110))

plt.title('Round %d' % 0)

plt.xlabel('PlayerID')

plt.ylabel('Fortune')

plt.savefig('graph3_round_%d.png' % 0, dpi=200)

# 绘制起始图片

def graph3(data,start,end,length):

for n in list(range(start,end,length)):

datai = pd.DataFrame({'money':data.iloc[n],'color':'gray'})

datai['color'].loc[[1,11,21,31,41,51,61,71,81,91]] = 'red'

datai = datai.sort_values(by = 'money').reset_index()

plt.figure(figsize = (10,6))

plt.bar(datai.index,datai['money'],color=datai['color'],alpha = 0.8,width = 0.9)

plt.grid(color='gray', linestyle='--', linewidth=0.5)

plt.ylim((-200,400))

plt.xlim((-10,110))

plt.title('Round %d' % n)

plt.xlabel('PlayerID')

plt.ylabel('Fortune')

plt.savefig('graph3_round_%d.png' % n, dpi=200)

# 创建绘图函数2

graph3(game3_result,10,100,10)

graph3(game3_result,100,1000,100)

graph3(game3_result,1000,17400,400)

print('finished!')

财富值变化

round17000

一分耕耘一分收获,努力的10人都冲到群体前列,财富值均有所提升,更包揽财富榜前三。所以说,努力是有回报的。

3.4 结果分析

富人和穷人的区别

模拟游戏考虑的角度较为简单,但清晰可见的是富人和穷人的关键区别无非两个字——努力。穷人总在抱怨壮志难酬,却很少发现富人之所以为富,在于他肯多下的1%努力,这将在多年后形成明显的差异。

然而现实更残酷,富人往往付出穷人500%的努力,甚至更多。马云上千亿身家,花费多少倍常人的努力,无法估量。

今天你努力了吗?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值