背景介绍

本数据集包括了2015年至2017年我国36个主要一线城市、特区的一些年度数据,包括产值、人口、就业、教育、医疗、经济贸易、房地产投资等方面。

包含文件:

  • 2015年国内主要城市年度数据.csv
  • 2016年国内主要城市年度数据.csv
  • 2017年国内主要城市年度数据.csv

数据特征

数据集名称 数据类型 特征数 包含城市数量 缺失值 相关人物
国内主要城市年度数据 数值型、字符型 13 36 描述性分析(可视化)等

数据属性

NO 字段名称 数据类型 字段描述
1 地区 String 城市名称
2 年份 Int 数据所对应的时间
3 国内生产总值 Float 单位:亿元
4 第一产业增加值 Float 单位:亿元
5 第二产业增加值 Float 单位:亿元
6 第三产业增加值 Float 单位:亿元
7 社会商品零售总额 Float 单位:亿元
8 货物进出口总额 Float 单位:百万美元
9 年末总人口 Float 单位:万人
10 在岗职工平均工资 Int 单位:元
11 普通高等学校在校学生数 Float 单位:万人
12 医院、卫生院数 Int 单位:个
13 房地产开发投资额 Float 单位:亿元

数据来源

国家统计局:https://data.stats.gov.cn/easyquery.htm?cn=E0105
分析非常常用的知识点,知识点概述如下:

1、数据集基本信息探索
    数据基本情况
    数量探索
    相关性分析
    绘总统计
    数据抽样
2、应用函数 apply
3、合并数据
4、索引问题
5、排序问题
6、重复数据处理
7、数据分组
8、处理缺失值
9、选择数据
10、pandas时间序列
11、pandas可视化

1、pandas 基本信息探索

(1) 基本情况

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

中文设置

plt.rcParams['font.sans-serif'] = ["SimHei"]
df = pd.read_csv('data/2015年国内主要城市年度数据.csv')
print('--' * 20, '\n【1】数据集基本情况探索')

print('\n>>>样本形状:\n', df.shape) # 样本形状、样本数、特征数探索
print('\n>>>样本索引、列名探索:\n', df.index, df.columns) # 样本索引、索引转换成列表、列名探索
print('\n>>>某列类型、全部样本类型探索:\n', df['年份'].dtypes, '\n', df.dtypes) # 某列类型、全部样本类型探索
print('\n>>>')
print(df.info())

(2) 数量探索

探索某列、全部样本非 NA 值的数量

print(df['年份'].count(), '\n', df.count())

探索某列的值,也可以探索全部样本的值

df['年份'].values

value_counts探索某列中各元素值出现的次数(只能探索某列的)

count 计算每列或每行的非NA单元格。

df['第一产业增加值'].value_counts().head()
df['年份'].value_counts().head()

unique()函数用于获取Series对象的唯一值。唯一性按出现顺序返回。基于哈希表的唯一,因此不排序

print("唯一值:\n",df['国内生产总值'].unique())

nunique唯一值得数量

print("\n唯一值的数量:\n",df['国内生产总值'].nunique())
print("唯一值:\n",df['年份'].unique())

nunique唯一值得数量

print("\n唯一值的数量:\n",df['年份'].nunique())

探索每一列缺失值数量

print("探索每一列缺失值数量:\n",df.isnull().sum())

不是缺失值数量

print("\n不是缺失值数量:\n",df.notnull().sum())

某列取值、多列取值

print('取出一列:\n', df['年份'].head(),"类型:",type(df['年份']))

取出多列:

print('\n取出多列:\n', df[['地区', '年份']].head(), "类型:", type(df[['地区', '年份']]))

(3) 相关性分析

探索特征之间相关性

探索某列、全部样本的方差

print('年末总人口方差:\n', df['年末总人口'].var())

print('\n总体数据方差:\n', df.var(), )

探索某列、全部样本的标准差

print('年末总人口标准差:\n', df['年末总人口'].std())

print('\n总体数据标准差:\n', df.std(), )

(4) 汇总统计

样本数据汇总统计

每一列求和

print('每一列求和:\n', df.sum())

某列逐行累加(可以全部样本每一列都累加)

print(df['地区'].cumsum().head())

最大最小值

print('最大值>>>\n', df.max().head())
print('\n最小值>>>\n', df.min().head())

返回 '国内生产总值' 列最大、最小值所对应的索引号

print('\n>>>', df['国内生产总值'].idxmax(), '\n', df['国内生产总值'].idxmin())
print('\n>>>', df.mean(), df.median()) # 平均值、中位数

汇总统计信息,是上面方法的统一

print('\n>>>', df.describe().T)
df.describe()
for (columnName, columnData) in df.iteritems():
print('Colunm Name : ', columnName)
print('Column Contents : ', columnData.values)
print("===============")

(5) 数据抽样

有时候我们做研究分析或者数据量过大时,
只希望抽取一部分数据做研究,因此要进行数据抽样处理

replace允许或不允许对同一行进行多次采样,默认就是False

data = df.sample(n=5, replace=False) # 不放回随机抽样 5 个数据
data

2、pandas 中的应用函数 apply

我们发现数据集中有浮点型数据,但是我们只需要整形数据,
因此我们很有必要使用应用函数对原数据进行类型转换

def fun(x):
x = int(x)
return x

data1 = df['国内生产总值'].apply(fun)

data1.head()
data2 = df['地区'].apply(lambda x: x + 'QQ')
data2.head()
data3 = df.iloc[:, :].apply(np.sum)
data3.head()

3、合并数据

df1 = pd.read_csv('data/2015年国内主要城市年度数据.csv')
df2 = pd.read_csv('data/2016年国内主要城市年度数据.csv')
df3 = pd.read_csv('data/2017年国内主要城市年度数据.csv')

通常用来连接DataFrame对象。默认情况下是对两个DataFrame对象进行纵向连接,

当然通过设置参数,也可以通过它实现DataFrame对象的横向连接

df_1 = pd.concat(objs=[df1, df2, df3]) # 合并数据,以行的维度合并
df_1.sample(n=7, replace=False) # 随机不放回抽样 7 个数据

以指定值合并,在本案例中不适用

df_2 = pd.merge(left=df1, right=df2, on='地区', how='outer')
df_2

4、索引问题

单个索引,inplace=False 不覆盖的情况下,
要使用一个变量 来间接操作

设置索引时的情况

d = df_1.set_index(keys='年份')
print(d.iloc[: , :4].head())

注意在取消索引操作时,inplace=True 设置为 True,以便后面可以查看到取消后的情况

d.reset_index(inplace=True)
d.iloc[: , :4].head() # 取消索引时的情况

多级索引

inplace=True 覆盖的情况下,直接使用 df_1 访问.

注意:

   在 inplace=True 覆盖原数据情况下,运行第 2 或多次,
  就会出现报错的情况,同时代码并没有语法错误,
  原因是原数据被覆盖了。解决方法是:重新运行所有代码,
  如果不是很必要,尽量不要执行覆盖原数据的操作

df_1.set_index(keys=['地区', '年份'], inplace=True) # 设置多级索引,覆盖原数据
print(df_1.iloc[: , :4].head())

df_1.reset_index(inplace=True)
df_1.iloc[: , :4].head()

5、排序问题

通过索引排序

data = df_1.sample(n=5, replace=False) # 通过随机不放回抽样 5 个数据

通过索引排列,升序排列、不覆盖原数据、如有缺失值则放在前面

data.sort_index(ascending=True, na_position='first')

多重索引的dataframe

dataframe.sort_index(level=[0,1],ascending=[False,True])

  • level 按指定索引级别的值排

通过指定列的值排序

df_1.sort_values(by=['地区', '年份'], ascending=[True, False], inplace=False, na_position='first').head(7)

6、重复数据处理

返回唯一值

print('\n>>>', df_1['地区'].unique()) # 唯一值元素
print('\n>>>\n', df_1.nunique()) # 唯一值数量

重复值处理

查找重复值

print('>>>\n', df_1.duplicated(subset=['年份'], keep='first').head())

删除重复值

print('>>>\n', df_1.drop_duplicates(subset=['年份'], keep='first', inplace=False).iloc[:, :4])

查找重复索引

print('\n>>>', df_1.index.duplicated())

7、数据分组

指定一列是聚合列,如:年份

'地区'作为索引分组,'年份'与分组列'地区'聚合

第一种方法

df_1.groupby(by=['地区'], as_index=True).agg({'年份': ['max', 'min', 'median']}).head()

第二种方法,两种方法是等效的

df_1.groupby(by=['地区'], as_index=True).年份.agg(['max', 'min', 'median']).head()

指定多列列是聚合列,如:年份、国内生产总值

df_1.groupby(by=['地区'], as_index=True).agg({'年份': 'max', '国内生产总值': 'describe'}).head()

没有指定聚合列,则代表选择所有列

返回所有列中的最大值

df_1.groupby(by=['地区'], as_index=True).max().head()

8、处理缺失值

在上面的探索中,发现有缺失值,因此有必要进行处理

查看所有数据的缺失情况

df_1.isnull().sum()

第一种方法,删除缺失值数据

df_1.dropna().isnull().sum()

第二种方法,使用填充法填充缺失值

print('\n>>>\n', df1.fillna(method='ffill').head()) # 使用缺失值的前一个值填充(前向填充)
print('>>>\n', df1.fillna(method='bfill').head()) # 使用缺失值的后一个值填充(后向填充)
''' 平均值填充(所有列填充) '''
print('>>>\n', df_1.fillna(value=df_1.mean()).head())

9、选择指定的数据

按标签选择

按行的序号、列的名称选择
df.loc[:, '列名']/df.loc[[0,1, 2], ['列名1', '列名2']] 

print('>>>\n', df_1.loc[:, '年份'].head())
print('>>>\n', df_1.loc[[0, 4, 7], ['年份', '国内生产总值']].head())

按位置选择

按行位置(序号)、列位置选择
df.iloc[:, :]/da.iloc[[0, 1, 2], [2, 3, 4]] 

print('>>>\n', df_1.iloc[:3, :3])
print('>>>\n', df_1.iloc[[1, 34, 56], [2, 4, 8]])

按条件来选择

筛选出符合条件的列
df_1 = df_1.set_index(["地区","年份"])

国内生产总值大于15678的数据

df_1[df_1['国内生产总值'] > 15678].head()

选择任一值大于1000的列

df_1.loc[:, (df_1>10000).any()]

选择所有值大于1000的列

df_1.loc[:, (df_1>1000).all()]
df_1.loc[:, df_1.isnull().any()] # 选择含 NaN值的列
df_1.loc[:, df_1.notnull().all()] # 选择不含NaN值的列

query和filter

在使用pandas进行数据分析时,经常遇到需要过滤信息的场景,此时我们可以用到2种函数,query和filter。

query函数

query函数我认为类似sql语言中的where,可以对dataframe中的特定column进行筛选。具体语法如下:

df.query('列名   判断   值'),如df.query('column1 > 2 and column 2<1')

等于

df[df[列名] 判断 值],如 df[df[column1]>2 & df[column2]<1]

filter函数

filter常规用法,在pandas说明里很好找到:

DataFrame.filter(items=None, like=None, regex=None, axis=None)

#items对列进行筛选#regex表示用正则进行匹配#like进行筛选#axis=0表示对行操作,axis=1表示对列操作

选择指定的列,类似于 df[['某列', '某列']]

df_1.filter(items=['地区', '年份']) # 选择指定的列
df_1.filter(like='产业', axis=1) # 选择含有 "产业" 的列

完整代码

from random import sample
import pandas as pd

df = pd.read_csv("./2015年国内主要城市年度数据.csv")

# values_count
v_c = df["年份"].value_counts()
# print(v_c)  # 2015    36
# Name: 年份, dtype: int64

# 唯一值
un = df["年份"].unique()  # 唯一值
# print(un)  # [2015]
un_num = df["年份"].nunique()  # 唯一值的数量
# print(un_num)  # 1

# 探索缺失值
# print(df.isnull().sum())  # 缺失
# print(df.notnull().sum())  # 完整

# 相关性分析
# print("年末总人口方差:\n", df["年末总人口"].var())
# print("总体数据方差:\n", df.var())

# print("年末总人口标准差:\n", df["年末总人口"].std())
# print("总体数据标准差:\n", df.std())


# 循环取出dec的值
# for (column_name, column_data) in df.describe().iteritems():
# print(column_name + ": ")
# print(column_data.values)


# 数据采样
# sample_data = df.sample(n=5, replace=False)
# print(sample_data)
# print("================")


# 数据合并
df1 = pd.read_csv("./2015年国内主要城市年度数据.csv")
df2 = pd.read_csv("./2016年国内主要城市年度数据.csv")
df3 = pd.read_csv("./2017年国内主要城市年度数据.csv")
df_1 = pd.concat(objs=[df1, df2, df3], axis=0)
sample_df_1 = df_1.sample(n=6, replace=False)
# print(sample_df_1)

# 将年份设置成索引
df11 = df.set_index("年份", inplace=False)
# print(df11.iloc[:,:4].head())

df12 = df11.reset_index(inplace=False)
# print(df12.iloc[:,:4].head())


# 找出重复值
print(df_1.duplicated(subset=["年份"], keep="last"))  # 最后一个出现的重复值为False
print(df_1.duplicated(subset=["年份"], keep="first"))  # 第一个出现的重复值为False
print(df_1.duplicated(subset=["年份"], keep=False))  # 重复值都为True
# 删除重复值
print(df_1.head())
df_drop_val = df_1.drop_duplicates(subset=["年份"], keep="first")
print(df_drop_val)

#