Python模拟社会财富分配——努力者和幸运儿谁更可能是富翁

 

一个财富分配游戏:

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

涉及的知识:

 

np.random.choice

Generates a random sample from a given 1-D array

numpy.random.choice(a, size=None, replace=True, p=None) 

  • a: 1-D ndarray,如果是int则生成np.arange(a),理解为从a中取样
  • size:抽样尺寸, (m, n, k), then m * n * k samples are drawn,默认None返回一个值
  • replace:个人理解为True放回采样,False不放回采样
  • p:1-D array-like,对应a中每个元素的抽样概率

DataFrame iloc loc

  • iloc:整数标签(从0行开始标签)
  • loc:轴标签(类似于行名称)

帕累托图绘图步骤(游戏二可视化中有代码)

  • sort_values对元素降序排列
  • 利用sum计算单个元素在总数中的占比
  • 利用cumsum计算概率的累积求和,找到80%的节点
  • 用bar画柱状图后,绘制累积的概率图。
  • 利用节点进行进行辅助线的标注

游戏一:没有借贷的社会

模型假设:

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

导入需要的包

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

import warnings
warnings.filterwarnings('ignore')

搭建模型

分为两种情况:

当所有人财富值都>0的时候,每个玩家都需要付1元钱。

当存在财富值=0的玩家,财富值不为0的玩家需要付1元钱。

因此在函数中用if进行筛选,分为两种情况构建函数。

def game1(data,roundi):
    if len(data[data[roundi-1]==0])>0:
        #当数据包含财富值为0的玩家,为0的玩家不需要出钱
        round_i=pd.DataFrame({'pre_round':data[roundi-1],'lost':0})
        con=round_i['pre_round']>0#筛选>0的玩家bool值
        round_i['lost'][con]=1#符合条件的lost=1
        roundi_players_i=round_i[con]#筛选总玩家数用于choice函数
        #利用choice函数,随机选择收到1元钱的玩家
        choice_i=pd.Series(np.random.choice(person_n,len(roundi_players_i)))
        #利用value_counts计算每个玩家收到的钱总数
        gain_i=pd.DataFrame({'gain':choice_i.value_counts()})
        #按照index连接两个表,并填充缺失值(nan无法参与return中的计算)
        round_i=round_i.join(gain_i)
        round_i.fillna(0,inplace=True)
        #玩家本轮结束的财富=上一轮-付钱(只有财富值>0的lost=1)+得到(通过value_counts计算)
        return round_i['pre_round']-round_i['lost']+round_i['gain']
    else:
        #所有玩家都出1元钱
        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']

运行模型

#构建最初财富值,均为100
person_n=[x for x in range(1,101)]
fortune=pd.DataFrame([100 for i in range(100)],index&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值