0%

CFPS数据分析案例

文献引用

刘保中.我国城乡家庭教育投入状况的比较研究——基于CFPS(2014)数据的实证分析[J].中国青年研究,2017(12):45-52.

文献简要

使用CFPS2014年的数据,在教育期望、教育支出教育参与三个维度上对当前我国城乡家庭教育投入状况进行了比较分析,详细摘要内容如下:

数据处理(Python)

数据概要

该文献使用的是cfps2014年的数据,且着重使用的是儿童数据,文献中的数据部分摘要如下:

数据清洗

导入必要的包

1
2
3
import numpy as np
import statsmodels.api as sm
from pandas.io.stata import StataReader

导入数据

导入了儿童数据和家庭数据(均为stata文件),使用StataReader函数读入该类型文件

1
2
child_stata = StataReader('cfps2014child.dta', convert_categoricals=False)
famecon_stata = StataReader('cfps2014famecon.dta', convert_categoricals=False)

上述方式得到的是stata数据,接着将其转化为Pandas中的DataFrame格式,使用read函数

1
2
child_df = child_stata.read()
fam_df = famecon_stata.read()

数据概览

1
print(child_df.head())

输出:

1
2
3
4
5
6
           pid  proxyrpt  ...  cfps2014eduy_im  releaseversion
0 100453401.0 1.0 ... 0.0 2.0
1 103924504.0 1.0 ... 0.0 2.0
2 106561502.0 1.0 ... 0.0 2.0
3 107624502.0 1.0 ... 0.0 2.0
4 110011103.0 1.0 ... 8.0 2.0

变量引入及预处理

使用的变量及处理方式:父母对孩子的教育期望(分为高等教育期望和非高等教育期望,以及等价转化为教育年限)、家庭全年教育支出、家庭教育课外补习支出、家庭教育参与(共六个变量,程度从低到高划为1-5分)。控制变量:孩子户口(0-农业户口,1-非农业户口)、孩子性别(0-女,1-男),孩子年龄、孩子目前上学阶段(小学及以上)、家庭年收入(取对数)。文献中使用的变量详情(部分划线的变量未引入):

特征变量详情列表如下:

1
2
3
4
5
6
7
8
child_col = ['fid14',  # 14年家庭编码
'wd2', # 家庭教育期望
'wd503m', 'wd5ckp', 'wd5total_m', 'wd5total', # 家庭教育支出: 课外辅导费用,是否确认教育支出,新教育支出,旧教育支出
'wf601m', 'wf602m', 'wf603m', 'wf604m', 'wf605m', 'wf606m', # 家庭教育参与: 频率从低到高(赋值1-5分)
'wa4', 'cfps2014_age', 'cfps_gender', # 控制变量: 户口(1:农, 3:非农),年龄,性别
'wf301m'] # 上哪级学校
family_col = ['fid14',
'finc'] # 家庭年收入

  1. 使用家庭收入变量连接两表
    为了在儿童数据中引入家庭数据的收入变量,需根据家庭编码链接两个表,使用join函数,键值设为家庭编码fid14特别要注意的是,因为不是每一个儿童在家庭表中的都有年收入这个数据,故连接后无年收入数据的儿童该值将为空,此时抛弃空值。并抛弃不符合要求的数据(-1)

    1
    2
    3
    4
    # 获取家庭年收入变量
    child_df = child_df.join(fam_df.set_index('fid14'), on='fid14') # 根据家庭编码链接两个表
    child_df = child_df.dropna()
    child_df.drop(child_df[child_df['finc'] < 0].index, inplace=True)
  2. 处理家庭收入变量
    进行取对数处理,自定义函数cal_finc进行映射。
    自定义函数cal_finc如下

    1
    2
    3
    4
    5
    6
    def cal_finc(finc):
    # 家庭年收入取对数
    if finc == 0:
    return 0
    else:
    return np.log(finc)

将函数映射到数据

1
child_df['finc'] = child_df['finc'].map(cal_finc)      # 处理家庭年收入

  1. 处理户口变量
    将原来的数据中农业户口和非农业户口映射为0和1

    1
    2
    city_code = {1: 0, 3: 1}  # 户口重新编码
    child_df['wa4'] = child_df['wa4'].map(city_code)
  2. 删去不符合条件的数据
    删去既不是农业户口或非农业户口的,再删去上学阶段不符合要求的

    1
    2
    3
    4
    drop_cond = (child_df['wa4'] < 1) | (child_df['wa4'] > 3)  # 删去户口不符合要求的
    child_df.drop(child_df[drop_cond].index, inplace=True)
    drop_cond1 = (child_df['wf301m'] <= 2) # 删去上学阶段不符合要求的
    child_df.drop(child_df[drop_cond1].index, inplace=True)

处理教育期望

  1. 首先删去不符合要求的教育期望样本

    1
    2
    drop_cond2 = (child_df['wd2'] < 0)
    child_df.drop(child_df[drop_cond2].index, inplace=True)
  2. 教育期望的分布以及样本量
    打印出教育期望的分布及样本数量

    1
    print(child_df['wd2'].value_counts(), 'count: ', child_df['wd2'].count())

输出:

1
2
3
4
5
6
7
8
9
6.0    2394
4.0 546
8.0 296
5.0 280
7.0 145
3.0 88
2.0 18
9.0 1
Name: wd2, dtype: int64 count: 3768

  1. 将教育期望映射为两类:1-高等教育期望,0-非高等教育期望

    1
    child_df['high_edu'] = child_df.apply(lambda row: 1 if row['wd2'] >= 5 else 0, axis=1)  # 是否为高等教育期望
  2. 将教育期望映射为教育年限

    1
    2
    edu_code = {9: 0, 8: 23, 7: 19, 6: 16, 5: 15, 4: 12, 3: 9, 2: 6}  # 教育期望重新编码
    child_df['wd2_years'] = child_df['wd2'].map(edu_code)
  3. 各个教育期望年限和高等教育期望的样本量、均值和百分比

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    village_df = child_df[child_df['wa4'] == 0]  # 农业户口
    city_df = child_df[child_df['wa4'] == 1] # 非农业户口
    expect_total_mean = child_df['wd2_years'].mean()
    village_expect_mean = village_df['wd2_years'].mean()
    print('total city village')
    print('count: ', child_df.shape[0], city_df.shape[0], village_df.shape[0])
    print('years_mean: ', expect_total_mean, city_expect_mean, village_expect_mean)
    print('high_edu_percent: ',
    child_df['high_edu'].value_counts(normalize=True).loc[1]*100,
    city_df['high_edu'].value_counts(normalize=True).loc[1]*100,
    village_df['high_edu'].value_counts(normalize=True).loc[1]*100)

输出:

1
2
3
4
total   city   village
count: 3768 808 2960
years_mean: 15.795912951167729 16.521039603960396 15.597972972972974
high_edu_percent: 82.6963906581741 93.6881188118812 79.69594594594595

原文中教育期望的数据分布如下:

处理教育支出

课外辅导数据较为正常,不需要处理

  1. 获取最终的全年教育支出

    1
    child_df['edu_expense'] = child_df.apply(lambda row: row['wd5total_m'] if (row['wd5ckp'] == 1) | (row['wd5ckp'] == 3) else row['wd5total'], axis=1)
  2. 删去不符合条件的数据

    1
    child_df.drop(child_df[child_df['edu_expense'] < 0].index, inplace=True)
  3. 各个全年教育指出和课外辅导的样本量、均值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 教育支出: 课外辅导
    coach_total_mean = child_df['wd503m'].mean()
    village_coach_mean = village_df['wd503m'].mean()
    city_coach_mean = city_df['wd503m'].mean()
    # 教育支出: 总支出
    expense_total_mean = child_df['edu_expense'].mean()
    village_expense_mean = village_df['edu_expense'].mean()
    city_expense_mean = city_df['edu_expense'].mean()
    child_df.to_csv('2014child.csv', index=False)
    print('total city village')
    print('count: ', child_df.shape[0], city_df.shape[0], village_df.shape[0])
    print('expense_mean: ', expense_total_mean, city_expense_mean, village_expense_mean)
    print('coach_mean: ', coach_total_mean, city_coach_mean, village_coach_mean)

输出

1
2
3
4
total   city   village
count: 3774 808 2966
expense_mean: 3179.1073131955486 5691.209158415842 2494.7585974376266
coach_mean: 787.992315845257 2657.6992574257424 278.64531355360754

原文中教育支出的数据分布如下:

处理教育参与

教育参与相关变量列表

1
li = ['wf601m', 'wf602m', 'wf603m', 'wf604m', 'wf605m', 'wf606m']

  1. 删去不符合条件的数据

    1
    2
    3
    4
    5
    nan_cond = False
    for col in child_df.columns:
    if col in li:
    nan_cond = nan_cond | (child_df[col] == -8) | (child_df[col] == -1)
    child_df.drop(child_df[nan_cond].index, inplace=True)
  2. 根据关心程度从大到小编码(5-1)

    1
    2
    3
    4
    care_code = {1: 5, 2: 4, 3: 3, 4: 2, 5: 1}  # 教育关心程度重新编码
    for col in child_df.columns:
    if col in li:
    child_df[col] = child_df[col].map(care_code)
  3. 关怀程度在2次以上的各个比例及样本量
    首先将频次变量映射为0-1变量,满足条件的为1

    1
    2
    3
    4
    # 频次在两次以上,即>=4
    for col in child_df.columns:
    if col in li:
    child_df[col] = child_df[col].map(lambda val: 1 if val >= 4 else 0)

进行统计

1
2
3
4
5
6
7
print('total   city   village')
print('count: ', child_df.shape[0], city_df.shape[0], village_df.shape[0])
for col in child_df.columns:
if col in li:
print(child_df[col].value_counts(normalize=True).loc[1]*100,
city_df[col].value_counts(normalize=True).loc[1]*100,
village_df[col].value_counts(normalize=True).loc[1]*100)

输出(顺序与原文一致):

1
2
3
4
5
6
7
8
total   city   village
count: 3746 802 2944
72.61078483715964 79.30174563591022 70.78804347826086
54.00427122263748 63.71571072319202 51.358695652173914
87.26641751201282 88.5286783042394 86.9225543478261
56.620395088093964 66.20947630922693 54.00815217391305
65.02936465563268 66.08478802992519 64.74184782608695
38.57447944474106 40.64837905236908 38.00951086956522

原文中教育参与的变量分布如下:

结束

本文标题:CFPS数据分析案例

文章作者:SkecisAI

发布时间:2019年10月24日 - 20:24:49

最后更新:2019年12月15日 - 16:27:27

原始链接:http://www.skecis.top/2019/10/24/CFPS数据分析案例/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

感谢你的支持,希望本文能助你一臂之力。