App下載

用Python分析了5萬條相親網(wǎng)站數(shù)據(jù),看相親男女畫像

猿友 2021-02-06 17:29:50 瀏覽數(shù) (3002)
反饋

作者:葉庭云

來源:公眾號(hào) 修煉Python

這短短的一生,我們最終都會(huì)失去。你不妨大膽一些,愛一個(gè)人,攀一座山,追一個(gè)夢(mèng)。

一、前言

數(shù)據(jù)來源:www.zhenai.com/zhenghun/ 本文利用 Python 分析了按城市尋找所有地區(qū)的征婚信息,看看相親男女的畫像。

二、數(shù)據(jù)查看和預(yù)處理

導(dǎo)入用到的庫

import pandas as pd
import re

讀取數(shù)據(jù),查看前 5 行

df = pd.read_excel('marriage.xlsx')
df.head()

結(jié)果如下:

查看索引、數(shù)據(jù)類型和內(nèi)存信息

df.info()

可以看到數(shù)據(jù)都沒有缺失值。

獲取到的數(shù)據(jù)里,居住地是各地區(qū)的,為了便于分析,需要處理成省級(jí)行政區(qū),學(xué)歷/月薪那一列數(shù)據(jù),有些是月薪,有些是學(xué)歷,可以分別處理成兩列數(shù)據(jù),是學(xué)歷的,提取出學(xué)歷層次,月薪標(biāo)記為 "未知";是月薪的,提取出月薪并計(jì)算,學(xué)歷標(biāo)記為 "未知"。

# 獲取34個(gè)省級(jí)行政區(qū)域,包括23個(gè)省,5個(gè)自治區(qū),4個(gè)直轄市,2個(gè)特別行政區(qū)的名稱
with open('地區(qū).txt', 'r', encoding='utf-8') as f:
    area = f.read().split('\\n')


print(area)
print(len(area))

結(jié)果如下:

['北京', '上海', '天津', '重慶', '黑龍江', '吉林', '遼寧', '內(nèi)蒙古', '河北', '新疆', '甘肅', '青海', '陜西', '寧夏', '河南', '山東', '山西', '安徽', '湖北', '湖南', '江蘇', '四川', '貴州', '云南', '廣西', '西藏', '浙江', '江西', '廣東', '福建', '臺(tái)灣', '海南', '香港', '澳門']
34
areas_list = []
for i in df['居住地']:
    for j in area:
        if j in i:
            areas_list.append(j)
            break
    else:
        areas_list.append('未知')


df['居住地'] = areas_list
df.head()

結(jié)果如下:

with open('學(xué)歷.txt', 'r', encoding='utf-8') as fp:
    edu = fp.read().split('\\n')


print(edu)

結(jié)果如下:

['博士', '碩士', '本科', '大專', '中專', '高中', '初中', '小學(xué)']
salary_list = []
edu_list = []
for item in df['學(xué)歷/月薪']:
    if '元' in item:   # 這一列的數(shù)據(jù)是表達(dá)月薪的話  計(jì)算
        data = re.findall('\\d+', item)
        data = [int(x) for x in data]
        salary = int(sum(data) / len(data))  # 取整
        salary_list.append(salary)
        edu_list.append('未知')
    else:
        salary_list.append('未知')
        for e in edu:
            if e in item:
                edu_list.append(e)
                break
        else:
            edu_list.append('未知')


print(len(edu_list))
print(len(salary_list))
df['學(xué)歷'] = edu_list
df['月薪'] = salary_list
df.head()      

結(jié)果如下:

這時(shí)候數(shù)據(jù)處理好了,可以刪掉學(xué)歷/月薪這一列,再重新保存到 Excel blank。

del df['學(xué)歷/月薪']
df

df.to_excel('處理后數(shù)據(jù).xlsx', index=False)

三、數(shù)據(jù)分析

相親男女性別占比?

# -*- coding: UTF-8 -*-
"""
@File    :男女占比情況.py
@Author  :葉庭云
@CSDN    :https://yetingyun.blog.csdn.net/
"""
import pandas as pd
import collections
from pyecharts.charts import Pie
from pyecharts import options as opts
from pyecharts.globals import ThemeType, CurrentConfig


# 引用本地js資源渲染
CurrentConfig.ONLINE_HOST = 'D:/python/pyecharts-assets-master/assets/'
# 提取數(shù)據(jù)
df = pd.read_excel('處理后數(shù)據(jù).xlsx')
gender = list(df['性別'])
# 統(tǒng)計(jì)男女人數(shù)
gender_count = collections.Counter(gender).most_common()
gender_count = [(k, v) for k, v in gender_count]


pie = Pie(init_opts=opts.InitOpts(theme=ThemeType.MACARONS))
# 富文本效果  環(huán)圖
pie.add('性別', data_pair=gender_count, radius=["40%", "55%"],
        label_opts=opts.LabelOpts(
            position="outside",
            formatter="{a|{a}}{abg|}\\n{hr|}\\n {b|: }{c}  {per|lmryjpg%}  ",
            background_color="#eee",
            border_color="#aaa",
            border_width=1,
            border_radius=4,
            rich={
                "a": {"color": "#999", "lineHeight": 22, "align": "center"},
                "abg": {
                    "backgroundColor": "#e3e3e3",
                    "width": "100%",
                    "align": "right",
                    "height": 22,
                    "borderRadius": [4, 4, 0, 0],
                },
                "hr": {
                    "borderColor": "#aaa",
                    "width": "100%",
                    "borderWidth": 0.5,
                    "height": 0,
                },
                "b": {"fontSize": 16, "lineHeight": 33},
                "per": {
                    "color": "#eee",
                    "backgroundColor": "#334455",
                    "padding": [2, 4],
                    "borderRadius": 2,
                },
            },
        ),)
pie.set_global_opts(title_opts=opts.TitleOpts(title='相親男女占比情況'))
pie.set_colors(['red', 'blue'])   # 設(shè)置顏色
pie.render('男女占比情況.html')

結(jié)果如下:

相親男女中女士多于男士。男士有 25910 人,占比 45.72%;女士有 30767 人,占比 54.28%。

相親男女年齡分布?

# -*- coding: UTF-8 -*-
"""
@File    :年齡分布.py
@Author  :葉庭云
@CSDN    :https://yetingyun.blog.csdn.net/
"""
import pandas as pd
import collections
from pyecharts.charts import Bar
from pyecharts.globals import ThemeType, CurrentConfig
from pyecharts import options as opts


CurrentConfig.ONLINE_HOST = 'D:/python/pyecharts-assets-master/assets/'


df = pd.read_excel('處理后數(shù)據(jù).xlsx')
age = list(df['年齡'])
age_count = collections.Counter(age).most_common()
# 按年齡排序
age_count.sort(key=lambda x: x[0])
age = [x[0] for x in age_count]
nums = [y[1] for y in age_count]


# print(age_count)
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.MACARONS))
bar.add_xaxis(age)
bar.add_yaxis('人數(shù)', nums)  # 數(shù)據(jù)多的時(shí)候設(shè)置不顯示標(biāo)簽
bar.set_global_opts(title_opts=opts.TitleOpts(title='相親男女年齡分布'))
# 標(biāo)記最大值  最小值  平均值   標(biāo)記平均線
bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False),
                    markpoint_opts=opts.MarkPointOpts(
                    data=[
                        opts.MarkPointItem(type_="max", name="最大值"),
                        opts.MarkPointItem(type_="min", name="最小值"),
                        opts.MarkPointItem(type_="average", name="平均值")]),
                    markline_opts=opts.MarkLineOpts(
                    data=[
                        opts.MarkLineItem(type_="average", name="平均值")]))
bar.render('年齡分布.html')

結(jié)果如下:

31歲的相親男女人數(shù)最多,有 2637 人,各個(gè)年齡段都有一定數(shù)量的相親男女,我們可以將年齡小于等于 20 歲,大于等于 70 歲的相親男女?dāng)?shù)據(jù)單獨(dú)提取出來看看。

import pandas as pd


df = pd.read_excel('處理后數(shù)據(jù).xlsx')
df1 = df[df['年齡'] <= 20]
df2 = df1['婚況'].value_counts()    # 統(tǒng)計(jì)小于等于20歲的相親男女的婚況
print(df2)

結(jié)果如下:

未婚    153
離異      6
喪偶      2
Name: 婚況, dtype: int64

大部分是未婚,年紀(jì)輕輕就那么急著相親嗎,再看看婚況是離異的數(shù)據(jù)。

import pandas as pd


df = pd.read_excel('處理后數(shù)據(jù).xlsx')
df1 = df[df['年齡'] <= 20]


df3 = df1[df1['婚況'] == '離異']
print(df3)

結(jié)果如下:

                網(wǎng)名  性別  ...  學(xué)歷     月薪
17425          微風(fēng)輕起  男士  ...  未知  50000
29645            媳婦  女士  ...  大專     未知
30398            仙妹  女士  ...  高中     未知
30485  會(huì)員1415395937  男士  ...  未知  35000
36684         微笑著變老  女士  ...  高中     未知
49864        風(fēng)吹動(dòng)了風(fēng)玲  女士  ...  高中     未知


[6 rows x 9 columns]

月薪寫著 50000、35000 的男士有些顯眼啊,在數(shù)據(jù)集中查看。

月薪 50000 的微風(fēng)輕起,征婚信息年齡寫的19,征婚宣言里又寫到 1994 年 26 歲;月薪 35000 的會(huì)員某某某,征婚信息年齡寫的 20,征婚宣言里又寫到 81 年的,看來網(wǎng)站里年齡、身高這些信息真實(shí)性值得懷疑。

相親男女婚況?

# -*- coding: UTF-8 -*-
"""
@File    :男女占比情況.py
@Author  :葉庭云
@CSDN    :https://yetingyun.blog.csdn.net/
"""
import pandas as pd
import collections
from pyecharts.charts import Pie
from pyecharts import options as opts
from pyecharts.globals import ThemeType, CurrentConfig


# 引用本地js資源渲染
CurrentConfig.ONLINE_HOST = 'D:/python/pyecharts-assets-master/assets/'
# 提取數(shù)據(jù)  婚況不為未填寫的
df = pd.read_excel('處理后數(shù)據(jù).xlsx')
data = df[df['婚況'] != '未填寫']
# 統(tǒng)計(jì)各婚況相親男女人數(shù)
data_count = collections.Counter(data['婚況']).most_common()
print(data)


c = (
    Pie()
    .add(
        "婚況",
        data_count,
        radius=["40%", "55%"],
        label_opts=opts.LabelOpts(
            position="outside",
            formatter="{a|{a}}{abg|}\\n{hr|}\\n {b|: }{c}  {per|bjvty5v%}  ",
            background_color="#eee",
            border_color="#aaa",
            border_width=1,
            border_radius=4,
            rich={
                "a": {"color": "#999", "lineHeight": 22, "align": "center"},
                "abg": {
                    "backgroundColor": "#e3e3e3",
                    "width": "100%",
                    "align": "right",
                    "height": 22,
                    "borderRadius": [4, 4, 0, 0],
                },
                "hr": {
                    "borderColor": "#aaa",
                    "width": "100%",
                    "borderWidth": 0.5,
                    "height": 0,
                },
                "b": {"fontSize": 16, "lineHeight": 33},
                "per": {
                    "color": "#eee",
                    "backgroundColor": "#334455",
                    "padding": [2, 4],
                    "borderRadius": 2,
                },
            },
        ),
    )
    .set_colors(["#8B008B", "#FF1493", "#000000"])
    .set_global_opts(title_opts=opts.TitleOpts(title="相親男女婚況"))
    .render("pie_rich_label.html")
)

結(jié)果如下:

相親男女婚況。離異的占比57.67%,所占比例最大,未婚占比34.14%,喪偶占比8.19%。

相親男女學(xué)歷分布情況?

# -*- coding: UTF-8 -*-
"""
@File    :學(xué)歷分布.py
@Author  :葉庭云
@CSDN    :https://yetingyun.blog.csdn.net/
"""
import pandas as pd
import collections
from pyecharts.charts import Pie
from pyecharts import options as opts
from pyecharts.globals import CurrentConfig


# 引用本地js資源渲染
CurrentConfig.ONLINE_HOST = 'D:/python/pyecharts-assets-master/assets/'
# 提取數(shù)據(jù)  學(xué)歷不為未知的
df = pd.read_excel('處理后數(shù)據(jù).xlsx')
data = df[df['學(xué)歷'] != '未知']
# print(data)
# 統(tǒng)計(jì)各學(xué)歷層次相親男女?dāng)?shù)量
data_count = collections.Counter(data['學(xué)歷']).most_common()
c = (
    # 寬  高  背景顏色
    Pie(init_opts=opts.InitOpts(width="800px", height="500px", bg_color="#2c343c"))
    .add(
        series_name="相親男女學(xué)歷",   # 系列名稱
        data_pair=data_count,         # 系列數(shù)據(jù)項(xiàng),格式為 [(key1, value1), (key2, value2)...]
        rosetype="radius",        # radius:扇區(qū)圓心角展現(xiàn)數(shù)據(jù)的百分比,半徑展現(xiàn)數(shù)據(jù)的大小
        radius="55%",             # 餅圖的半徑
        center=["50%", "50%"],    # 餅圖的中心(圓心)坐標(biāo),數(shù)組的第一項(xiàng)是橫坐標(biāo),第二項(xiàng)是縱坐標(biāo)
        label_opts=opts.LabelOpts(is_show=False, position="center"),   # 標(biāo)簽配置項(xiàng)
    )
    .set_colors(["#00BFFF", "#00FF7F", "#FF1493", "#8B008B", "#FFFF00", "#556B2F"])
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="相親男女學(xué)歷",
            pos_left="center",
            pos_top="20",
            title_textstyle_opts=opts.TextStyleOpts(color="#fff"),
        ),
        legend_opts=opts.LegendOpts(is_show=False),
    )
    .set_series_opts(
        tooltip_opts=opts.TooltipOpts(
            trigger="item", formatter="{a} <br/>: {c} (j8kdyx1%)"  # 'item': 數(shù)據(jù)項(xiàng)圖形觸發(fā),主要在散點(diǎn)圖,餅圖等無類目軸的圖表中使用
         ),
        label_opts=opts.LabelOpts(color="#fff"),
    )
    .render("相親男女學(xué)歷.html")
)

結(jié)果如下:

相親男女學(xué)歷大部分在高中(35.92%)、大專(24.72%),有近六成的相親男女。本科占比20.7%,中專占比16.35%,碩士、博士高學(xué)歷的相親男女人數(shù)很少,分別占比2.14%,0.17%

相親男女地區(qū)分布?

# -*- coding: UTF-8 -*-
"""
@File    :地區(qū)分布.py
@Author  :葉庭云
@CSDN    :https://yetingyun.blog.csdn.net/
"""
import pandas as pd
import collections
from pyecharts import options as opts
from pyecharts.charts import Geo
from pyecharts.globals import ChartType
from pyecharts.globals import ThemeType, CurrentConfig


CurrentConfig.ONLINE_HOST = 'D:/python/pyecharts-assets-master/assets/'


df = pd.read_excel('處理后數(shù)據(jù).xlsx')
area = list(df['居住地'])
area_count = collections.Counter(area).most_common(34)
print(area_count)


# 初始化配置項(xiàng)  背景顏色  大小  主題
geo = Geo(init_opts=opts.InitOpts(width='1000px', height='600px', theme=ThemeType.DARK))
# 設(shè)置是否顯示省份
geo.add_schema(maptype='china', label_opts=opts.LabelOpts(is_show=True))
# 繪制什么類型圖  熱力圖  漣漪圖等
geo.add('相親男女人數(shù)', data_pair=area_count, type_=ChartType.EFFECT_SCATTER)
geo.set_series_opts(label_opts=opts.LabelOpts(is_show=False))   # 不顯示數(shù)據(jù)標(biāo)簽
geo.set_global_opts(title_opts=opts.TitleOpts(title="相親男女地區(qū)分布"),
                 visualmap_opts=opts.VisualMapOpts(max_=5000, is_piecewise=True,   # 劃分區(qū)間是否精確
     pieces=[{"max": 1000, "min": 100, "label": "100-1000", "color": "#708090"},  # 分段  添加圖例注釋  和顏色
                            {"max": 1500, "min": 1001, "label": "1001-1500", "color": "#00008B"},
                            {"max": 2000, "min": 1501, "label": "1501-2000", "color": "#483D8B"},
                            {"max": 2500, "min": 2001, "label": "2001-2500", "color": "#1E90FF"},
                            {"max": 3000, "min": 2501, "label": "2501-3000", "color": "#8B008B"},
                            {"max": 5000, "min": 3001, "label": ">=3000", "color": "#FF0000"}])
                    )
geo.render('地區(qū)分布.html')

結(jié)果如下:

[('重慶', 4436), ('廣東', 2637), ('四川', 2519), ('山東', 2398), ('河南', 2160), ('上海', 2156), ('云南', 2039), ('北京', 2037), ('臺(tái)灣', 1997), ('安徽', 1920), ('江蘇', 1919), ('天津', 1918), ('黑龍江', 1918), ('湖南', 1800), ('新疆', 1799), ('遼寧', 1680), ('甘肅', 1680), ('廣西', 1679), ('湖北', 1679), ('內(nèi)蒙古', 1559), ('山西', 1440), ('福建', 1440), ('江西', 1440), ('浙江', 1440), ('陜西', 1439), ('河北', 1439), ('青海', 1339), ('貴州', 1200), ('吉林', 1080), ('西藏', 942), ('寧夏', 702), ('海南', 360), ('香港', 353), ('澳門', 117)]

重慶、廣東、四川等地區(qū)的相親男女人數(shù)最多。

征婚宣言一般是介紹自己情況,表達(dá)對(duì)另一半的要求和期望。下面我們分別來看看相親男女征婚宣言里關(guān)鍵詞都有些什么。

# -*- coding: UTF-8 -*-
"""
@File    :征婚宣言詞云.py
@Author  :葉庭云
@CSDN    :https://yetingyun.blog.csdn.net/
"""
import pandas as pd
import jieba
import collections
import re
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image


# 提取性別  征婚宣言這兩列數(shù)據(jù)就好
df = pd.read_excel('處理后數(shù)據(jù).xlsx')[['性別', '征婚宣言']]
# df1 = df[df['性別'] == '女士']['征婚宣言']
df2 = df[df['性別'] == '女士']['征婚宣言']


# 讀取停用詞數(shù)據(jù)
with open('stop_words.txt', encoding='utf-8') as f:
    con = f.read().split('\\n')    # 得到每一行的停用詞
    stop_words = set()
    for i in con:
        stop_words.add(i)


result_list = []
for data in df2:
    # 文本預(yù)處理  去除一些無用的字符   只提取出中文出來
    new_data = re.findall('[\\u4e00-\\u9fa5]+', data, re.S)
    new_data = "/".join(new_data)
    # 文本分詞
    seg_list_exact = jieba.cut(new_data, cut_all=True)
    # 去除停用詞和單個(gè)詞
    for word in seg_list_exact:
        if word not in stop_words and len(word) > 1:
            result_list.append(word)


print(result_list)
# 篩選后統(tǒng)計(jì)
word_counts = collections.Counter(result_list)
mask_ = 255 - np.array(Image.open('woman_mask.png'))
# 繪制詞云
my_cloud = WordCloud(
    background_color='white',  # 設(shè)置背景顏色  默認(rèn)是black
    mask=mask_,
    font_path='simhei.ttf',   # 設(shè)置字體  顯示中文
    max_font_size=112,        # 設(shè)置字體最大值
    min_font_size=12,         # 設(shè)置字體最小值
    random_state=88           # 設(shè)置隨機(jī)生成狀態(tài),即多少種配色方案
).generate_from_frequencies(word_counts)


# 繪制詞云
plt.figure(figsize=(8, 5), dpi=200)
# 顯示生成的詞云圖片
plt.imshow(my_cloud, interpolation='bilinear')
# 顯示設(shè)置詞云圖中無坐標(biāo)軸
plt.axis('off')
plt.savefig('woman_cloud.png', dpi=200)
plt.show()

結(jié)果如下:

相親男女征婚宣言里,喜歡、希望、生活、善良、真誠、真心、幸福、性格等都是出現(xiàn)頻率高的詞語。

2 人點(diǎn)贊