配数据文件:series.xlsx
excel文件下载地址:
链接:https://pan.baidu.com/s/1EkuKBPKnJW1muAGTVcVj7Q
提取码:dmjn
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
脚本介绍:主要写了Series序列与DataFrame数据框的常用函数以及数据处理的一些过程
博主:kitty.wang
"""
import pandas as pd
import numpy as np
from pandas import Series, DataFrame
"""
Series序列 输出类型为Series
Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近。Series能保存不同种数据类型,字符串、boolean值、数字等都能保存在Series中。
"""
# 方式一:通过一维数组创建
s = pd.Series([1, 4, '22']) # 默认index为0,1,2...
s[0] = 11 # 修改Series序列的值
print s
print 's.index: ', s.index
print 's.values: ', s.values
print 'type(s): ', type(s)
s.index = ['a', 'b', 'c'] # 修改索引名称
s['a'] = 33 # 修改数值
print s
s2 = pd.Series([1, 'aa', np.NaN], index=['a', 'b', 'c']) # 创建序列的同时定义索引名称
print s2
print pd.isnull(s2) # 判断s是否为空,返回布尔值
print s2 * 2 # 将数值*2,字符串则重复(如aa-->>aaaa)
print s2[s2 > 2]
# 方式二:通过字典创建
dic = {'hang1': 10, 'hang2': 20, 'hang3': 30.3}
s = pd.Series(dic)
print s
print 'type(s): ', type(s)
# 与list做对比
lis = [1, 4, '22']
print lis
print 'type(lis) ', type(lis) # 输出类型为list
# 运算(Series索引的自动化对齐)
s1 = pd.Series([1, 4, 6], index=['a', 'b', 'c'])
s2 = pd.Series([11, 44, 66], index=['a', 'b', 'd'])
# 由于s1中没有对应的d索引,s2中没有对应的c索引,所以数据的运算会产生两个缺失值NaN。
# 对于数据框DataFrame,除了行索引的自动对齐,列索引(变量名)也会自动对齐
print 's1+s2: ', s1+s2
print 's1/s2: ', s1/s2
# 查询
teacher = pd.read_excel('series.xlsx') # 如果excel文件与脚本文件不在同一个目录,需要在文件名前加文件路径
print 'teacher:'
print teacher
print teacher.head(2) # 读取前两行,默认读取前5行
print teacher.tail(2) # 读取后两行,默认读取后5行
print teacher.ix[[0, 2, 4]] # 读取索引为0, 2, 4的数据
print teacher[['sex', 'height']].head() # 读取列名为sex、height的前5行数据
print teacher.ix[[0, 1, 4, 5], ['sex', 'height']].head() # 读取索引为0, 1, 4, 5且列名为sex、height的前5行数据
# 特定条件查询
# 读取sex=F的数据(首先判断sex=F是否为真,若为真,则输出这一行的数据,否则不输出)
print teacher[teacher['sex'] == 'F']
# 读取sex=F且name=x的数据(首先判断sex=F且name=x是否为真,若为真,则输出这一行的数据,否则不输出)
print teacher[(teacher['sex'] == 'F') & (teacher['name'] == 'x')]
# 读取sex=F或name=y的数据(首先判断sex=F或name=y是否为真,若为真,则输出这一行的数据,否则不输出)
print teacher[(teacher['sex'] == 'F') | (teacher['name'] == 'y')]
# 读取sex=F或name=y的数据(首先判断sex=F或name=y是否为真,若为真,则输出这一行的列'name', 'height',否则不输出)
print teacher[(teacher['sex'] == 'F') | (teacher['name'] == 'y')][['name', 'height']]
# 统计分析
d1 = pd.Series(3*np.random.normal(size=50)+10) # 生成50个正态分布的数据,并乘以3,且加10,转化为Series
print 'd1:', d1
d2 = np.random.f(2, 5, size=50) # 从F分布中抽取样本。2为组间自由度,4为组内自由度,50为数量
print 'd2:', d2
d3 = np.random.randint(1, 100, size=50) # 生成50个1-100的整数
print 'd3:', d3
print 'd1.count():', d1.count() # 求非空元素的个数
print 'd1.min():', d1.min() # 求最小值
print 'd1.idxmin():', d1.idxmin() # 求最小值的位置
print 'd1.max():', d1.max() # 求最大值
print 'd1.idxmax():', d1.idxmax() # 求最大值的位置
print 'd1.quantile(0.25)', d1.quantile(0.25) # 25%分位数,又称‘第一四分位数’
print 'd1.sum()', d1.sum() # 求和
print 'd1.mean():', d1.mean() # 求均值
print 'd1.median():', d1.median() # 求中位数
print 'd1.mode():', d1.mode() # 求众数
print 'd1.var():', d1.var() # 求方差
print 'd1.mad():', d1.mad() # 求平均绝对偏差
print 'd1.skew():', d1.skew() # 求偏度,右偏(Sk>0)时一般算术平均数>中位数>众数,左偏(Sk<0)时众数>中位数>平均数,正态分布三者相等。
print 'd1.kurt():', d1.kurt() # 求峰度,峰度>0:该总体数据分布较为陡峭,为尖顶峰;峰度<0:该总体数据分布较为平坦,为平顶峰。峰度的绝对值数值越大表示其分布形态的陡缓程度与正态分布的差异程度越大。
print 'd1.describe():', d1.describe() # 一次性输出多个描述性统计指标:计数、均值、标准差、最小值、4分位数、最大值。只针对Series或DataFrame,一维数组是没有这个方法的
teacher2 = pd.read_excel('series.xlsx') # 如果excel文件与脚本文件不在同一个目录,需要在文件名前加文件路径
print '离散型数据的统计指标:\n', teacher2['sex'].describe() # 观测数量count、唯一值个数unique、众数水平top及个数freq
print '相关系数:\n', teacher2.corr() # 相关系数。相关系数的计算可以调用pearson方法或kendell方法或spearman方法,默认使用pearson方法
print '相关系数spearman:\n', teacher2.corr('spearman') # 相关系数
print 'corrwith\n', teacher2.corrwith(teacher2['height']) # 如果只想关注某一个变量与其余变量的相关系数的话,可以使用corrwith,如下方只关心x1与其余变量的相关系数:
print '协方差矩阵:\n ', teacher2.cov() # 协方差矩阵
# 排序:sort_values按照值来排序、sort_index按照索引来排序
se = pd.Series(np.array(np.random.randint(1, 100, 5)))
print se.sort_values() # 默认为升序
print se.sort_values(ascending=False) # 按照降序排序
print se.sort_index() # 默认为升序
print se.sort_index(ascending=False) # 按照降序排序
"""
DataFrame数据框 输出类型为DataFrame
二维的表格型数据结构,输出内容与mysql类似,有列名以及行索引。可以将DataFrame理解为Series的容器。
"""
# 方式一:通过字典方式创建
dataf = {'lie1': ['a', 'b', 'c'], 'lie2': [11, 33, 22]}
f1 = DataFrame(dataf) # 转化为DataFrame形式
print f1
f2 = DataFrame(dataf, columns=['lie1', 'lie2']) # 自定义输出列顺序
print f2
f3 = DataFrame(dataf, columns=['lie1', 'lie2'], index=['a1', 'a2', 'a3']) # 自定义索引名称
print f3
# 方式二:通过嵌套字典方式创建
dataf2 = {'lie1': {'hang1': 'py', 'hang2': 'java'}, 'lie2': {'hang1': 20, 'hang2': 30}}
# dataf2 = {'lie1': {'hang1': 'py', 'hang2': 'java'}, 'lie2': {'hang1': 20}}
d1 = DataFrame(dataf2)
print d1
d2 = DataFrame(dataf2, columns=['lie1', 'b', 'c']) # 生成新的DataFrame,没有定义值的列为NaN
print d2
d2['b'] = Series(['A', 'B'], index=['hang1', 'hang2']) # 修改某一列的值
d2['c']['hang2'] = 30 # 修改某一个数值
print d2
# 方式三:通过二维数组创建
arr = np.array(np.random.randint(0, 50, 12)).reshape(3, 4) # 随机生成0-50的12个数字,转化为三行四列
df = pd.DataFrame(arr)
print df
print type(df)
# 统计分析
d1 = pd.Series(3*np.random.normal(size=50)+10) # 生成50个正态分布的数据,并乘以3,且加10,转化为Series
d2 = np.random.f(2, 5, size=50) # 从F分布中抽取样本。2为组间自由度,4为组内自由度,50为数量
d3 = np.random.randint(1, 100, size=50) # 生成50个1-100的整数
d = pd.DataFrame(np.array([d1, d2, d3]).T, columns=['x1', 'x2', 'x3'])
print '3行50列的二维数组:\n', np.array([d1, d2, d3]) # 3行50列的二维数组
print '转置为50行3列的二维数组:\n', np.array([d1, d2, d3]).T # 转置为50行3列的二维数组
print 'df.head():\n', df.head()
# 定义一个函数:用于生成所有的统计描述指标
def describe_all(xx):
return pd.Series([xx.count(), xx.min(), xx.idxmin(),
xx.quantile(0.25), xx.median(),
xx.quantile(0.75), xx.mean(),
xx.max(), xx.idxmax(),
xx.mad(), xx.var(),
xx.std(), xx.skew(), xx.kurt()],
index=['Count', 'Min', 'Whicn_Min',
'Q1', 'Median', 'Q3', 'Mean',
'Max', 'Which_Max', 'Mad',
'Var', 'Std', 'Skew', 'Kurt'])
print d.apply(describe_all) # 对DataFrame的每一列都生成对应的统计描述指标
# 增删改
dic1 = {'lie1': {'hang1': 'aa', 'hang2': 'bb', 'hang3': 'cc'}, 'lie2': {'hang1': 20, 'hang2': 30, 'hang3': 40}}
df1 = pd.DataFrame(dic1)
dic2 = {'lie1': {'hang4': 'cc', 'hang5': 'dd', 'hang6': 'ee'}, 'lie2': {'hang4': 50, 'hang6': 70}}
df2 = pd.DataFrame(dic2)
# 新增:df2的数据加到df1中
df = pd.concat([df1, df2])
print df
# 删除
# del df # 删除对象
print df.drop(['hang4', 'hang6'], axis=0) # 删除行,不影响原来的数据。默认axis=0,表示删除行。
print df.drop(['lie1'], axis=1) # 删除列,不影响原来的数据
print df[df['lie2'] > 50] # 等价于删除lie2<=50的数据
print df
# 修改数值
df.ix[df['lie1'] == 'aa', 'lie2'] = 2000
print df
# 修改列名columns
df.rename(columns={'lie1': 'a', 'lie2': 'b'}, inplace=True)
print df
# 修改行名index
print df.reset_index() # 行名变为原始的数字
print df
# 聚合groupby()
dic1 = {'lie1': {'hang1': 'aa', 'hang2': 'bb', 'hang3': 'cc'}, 'lie2': {'hang1': 20, 'hang2': 30, 'hang3': 40}, 'lie3': {'hang1': '男', 'hang2': '男', 'hang3': '女'}, 'lie4':{'hang1': 2, 'hang2': 4, 'hang3': 2}}
df1 = pd.DataFrame(dic1)
dic2 = {'lie1': {'hang4': 'cc', 'hang5': 'dd', 'hang6': 'ee'}, 'lie2': {'hang4': 50, 'hang6': 60, 'hang6': 70}, 'lie3': {'hang4': '女', 'hang5': '男', 'hang6': '女'}, 'lie4':{'hang1': 4, 'hang2': 5, 'hang3': 6}}
df2 = pd.DataFrame(dic2)
df = pd.concat([df1, df2])
print df
print '聚合1:\n', df.groupby('lie3').mean() # 按照lie3分组,自动计算各数值型的组内均值
print '聚合2:\n', df.groupby(['lie3', 'lie4']).mean() # 按照lie3、lie4分组,自动计算各数值型的组内均值
print '聚合3:\n', df.drop('lie4', axis=1).groupby('lie3').mean() # 按照lie3分组,剔除列4后,自动计算各数值型的组内均值
print '聚合4:\n', df.drop('lie4', axis=1).groupby('lie3').agg([np.mean, np.median]) # 按照lie3分组,剔除列4后,自动计算各数值型的组内均值mean以及中位数median
# 排序:sort_index、sort_values
print '升序:\n', df.sort_values(by=['lie2', 'lie4']) # 根据指定列的值排序,默认为升序
print '降序:\n', df.sort_values(by=['lie2', 'lie4'], ascending=False) # 根据指定列的值排序,按照降序排序
print '索引升序:\n', df.sort_index() # 根据索引排序,默认为升序
print '索引降序:\n', df.sort_index(ascending=False) # 根据索引排序,按照降序排序
# 多表关联:merge
df1 = pd.DataFrame({'lie1': ['a', 'b', 'a', 'b', 'b'], 'lie2': range(5)})
print df1
df2 = pd.DataFrame({'lie1': ['a', 'c', 'c', 'c', 'c'], 'lie3': range(5)})
print df2
result1 = pd.merge(df1, df2) # 默认是两个表之间的内连接,关联条件为相同列名lie1。等价于 select * from df1 inner join df2 on df1.lie1=df2.lie1
print result1
result2 = pd.merge(df1, df2, how='left', left_on='lie2', right_on='lie3') # left为左连接;right为右连接;outer为外连接。等价于 select * from df1 left join df2 on df1.lie2=df2.lie3
print result2
"""
数据透视表
"""
dic1 = {'age': {'hang1': 11, 'hang2': 11, 'hang3': 20, 'hang4': 15}, 'lie2': {'hang1': 40, 'hang2': 30, 'hang3': 20, 'hang4': 40}, 'sex': {'hang1': '男', 'hang2': '男', 'hang3': '女', 'hang4': '男'}, 'lie4':{'hang1': 2, 'hang2': 6, 'hang3': 4, 'hang4': 2}}
df1 = pd.DataFrame(dic1)
print '数据透视表:\n', df1
print pd.pivot_table(df1, values=['lie2', 'lie4'], columns=['age', 'sex']) # 按照age跟sex分组,得到lie2跟lie4
print pd.pivot_table(df1, values=['lie2', 'lie4'], columns=['age', 'sex']).unstack() # 转化为列联表
print pd.pivot_table(df1, values=['lie2', 'lie4'], columns=['age', 'sex'], aggfunc=[np.mean, np.median, np.std]) # 求多个值
"""
多层索引:可以理解为excel中的合并单元格后的大标题
"""
df = pd.DataFrame(np.random.randint(10, 100, 20).reshape(5, 4), index=[['A', 'A', 'A', 'B', 'B'], [1, 2, 3, 1, 2]], columns=[['X', 'X', 'X', 'Y'], ['x1', 'x2', 'x3', 'y']])
print '多层索引:\n', df
print df['X'] # 取出列索引为X的数据
print df.ix[['A'], :] # 取出行索引为A的数据
# 相关分析
x = [52, 19, 7, 33, 2]
y = [162, 61, 22, 100, 6]
xmean = np.mean(x)
ymean = np.mean(y)
xsd = np.std(x)
ysd = np.std(y)
zx = (x - xmean) / xsd
zy = (y - ymean) / ysd
r = np.sum(zx * zy) / len(x)
print r
r = np.corrcoef(x, y)
print r
data = pd.DataFrame({'X': x, 'Y': y})
r = data.corr()
print r
# 绘图
import matplotlib.pyplot as plt
data1 = np.arange(10)
print data1
plt.plot(data1)
plt.xlabel('month')
plt.ylabel('order')
plt.title('tu_xing')
plt.show()
fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax1 = fig.add_subplot(2, 2, 2)
ax1 = fig.add_subplot(2, 2, 3)
plt.plot(np.random.rand(50).cumsum(), 'k--')