Python模块-pandas
数据分析虽说很多时候需要对业务和数据的理解,但其实大部分时候对数据的操作是相似(即使使用不同的工具,如Excel、Python、R等),像是数据清洗、表格结构修改、字段切分、分组计算等等。下面是使用Python中的Pandas包对数据分析常用操作的笔记。
数据读取
pandas读取文件后的数据集是一个DataFrame对象,该对象的每个列是一个Series对象
# pandas可读取很多文件格式
# 但一般读取数据的文件格式为:csv 和 excel
import pandas as pd
df = pd.read_csv("iris.csv",
sep=',',
names=["A","B","C","D"],
nrows=2, # 只要前两行的数据
encoding='utf-8'
)
df = pd.read_excel("iris.xlsx",
sheetname='XXXX',
header=0, # 指定第一行为表头
index_col=0, # 指定第一列为索引
usecols = [0, 2] # 只要第一和三列的数据
)
# 数据库读取
import pymysql # MySQL
import pymssql # SQLserver
conn = pymssql.connect(host='XXX.XX.XX.XX', user='username', password='123', database='DB')
OS = pd.read_sql("SELECT * FROM [KF_SZ].[dbo].[OSdepartrelation]",conn)
conn.close()
数据探索
# 查看数据量和特征量
df.shape
>>> (68630, 14)
# 查看数据集的头5行
df.head()
# 查看数据集的尾5行
df.tail()
# 查看行名
df.index
>>> RangeIndex(start=0, stop=68630, step=1)
# 查看列名
df.columns
>>> Index(['行号', '仓库', '货号', '条码', '商品名称'], dtype='object')
# 几乎用不上吧
df.values
# 查看数据格式
df.dtypes
>>> 行号 int64
仓库 object
货号 int64
条码 object
# 计数:每个特征(列)的非空数量
df.count()
>>> 商品名称 68630
规格 6340
单位 67719
库存数量 68630
# 计数:对单个列(Series)的频数统计
df['仓库'].value_counts()
>>> 公司总部总仓库 2016
佛山南海万科店 938
深圳宝安兴业店 928
深圳宝安百年店 907
# 返回唯一值的数组
df['区域'].unique()
>>> array(['深圳', '东莞', '广州', '佛山', '江门', '成都', '四川'], dtype=object)
# 统计描述:可以对整个数据集(DataFrame),也可以对单个列(Series)
df.describe()
df['库存数量'].describe()
>>> count 68630.000000
mean 19.545230
std 248.819321
min -1600.000000
25% 2.000000
50% 5.000000
75% 14.000000
max 38080.000000
Name: 库存数量, dtype: float64
# 小技巧
df.describe().astype(np.int64).T
数据清洗
数据清洗
# 单列字段清洗-去空格
df['商品名称'] = df['商品名称'].map(lambda s : s.strip())
df['A']=df['A'].map(str.strip) # 去除两边空格
df['A']=df['A'].map(str.lstrip) # 去除左边空格
df['A']=df['A'].map(str.rstrip) # 去除右边空格
df['A']=df['A'].map(str.upper) # 转大写
df['A']=df['A'].map(str.lower) # 转小写
df['A']=df['A'].map(str.title) # 首字母大写
# 字段切分,并创建新特征
df.loc[:,"区域"] = df['仓库'].map(lambda s:s[0:2])
类型转换
# 转换某特征(列)的数据格式
df['行号'] = df['行号'].astype(float)
# 转化时间格式
df['time']=pd.to_datetime(df['time'])
缺失值
- 缺失值查看
# 缺失值判断(在原数据对象以T/F替换)
df.isnull()
df.notnull()
df['A'].isnull()
- 缺失值统计
# 缺失值计数方法
# 方法一
df['A'].isnull().value_counts()
>>> True 68629
False 1
Name: A, dtype: int64
# 方法二
df['A'].isnull().sum()
>>> 68629
df.isnull().sum()
>>> 仓库 0
货号 0
条码 2
规格 62290
- 缺失值删除
# 默认axi=0,how='any': 按行,任意一行有NaN就整列丢弃
df.dropna()
df.dropna(axis=1)
# 一行中全部为NaN的,才丢弃
df.driopna(how='all')
# 保留至少3个非空值的行:一行中有3个值是非空的就保留
df.dropna(thresh=3)
- 缺失值填充
# 整个数据集填充
df.fillna(0)
# 有针对性的填充
df.fillna({'性别':'男', '年龄':30})
重复值
# 返回布尔向量、矩阵
df['A'].duplicated()
df.duplicated()
# 整个实例一模一样才删除,默认保留第一行
df.drop_duplicates()
# 保留k1列中的唯一值的行,默认保留第一行
df.drop_duplicates(subset=["k1"])
# 保留 k1和k2 组合的唯一值的行,take_last=True 保留最后一行
df.drop_duplicates(subset=["k1","k2"], take_last=True)
值替换
# 一对一替换
# 将df的A列中 -999 全部替换成空值
df["A"].replace(-999, np.nan)
# 多对一替换
# -999和1000 均替换成空值
obj.replace([-999,1000], np.nan)
# 多对 一对一替换
# -999替换成空值,1000替换成0
obj.replace([-999,1000], [np.nan, 0])
# 同上,写法不同,更清晰
obj.replace({-999:np.nan, 1000:0})
# 有趣的写法
dataset_raw.loc[dataset_raw['workclass'] == 'Without-pay', 'workclass'] = 'Not Working'
修改表结构
一般数据分析需要修改表结构都是在列上动手脚,注意操作有以下几种
新增列
# 方式一
df['test'] = 0
# 方式二
df.loc[:,"区域"] = df['仓库'].map(lambda s:s[0:2])
# 方式三
df.loc[:,"is_bonus"]=1
df.loc[df['remarks']=='无奖金', 'is_bonus'] = 0
# 方式四
# 需求:创建一个新变量test2
# 1.petal_length>2 and petal_width>0.3 = 1
# 2.sepeal_length>6 and sepal_width>3 = 2 3.其他 = 0
df.loc[(df['petal_length']>2)&(df['petal_width']>0.3), 'test2'] = 1
df.loc[(df['sepal_length']>6)&(df['sepal_width']>3), 'test2'] = 2
删除列
# 丢弃指定的特征(列)
df.drop(['行号','条码'],
axis=1,
inplace=True)
删除行
# 删除特色的行用得少,一般使用切片
df.drop(index=['no1','no2'],
axis=0,
inplace=True)
df.drop(df.index[[0,1]],
axis=0,
inplace=True)
修改列名
df.rename(columns = {'年':'compute_year',
'月/季度':'compute_month',
'员工编号':'code',
'员工姓名':'name',
'职位':'position',
'体系':'system_name',
'运营单位':'op_unit_name',
'区域':'sub_area_name',
'部门名称':'dept_name',
'员工所属小组': 'sub_dept_name'},
inplace=True)
数据分组(数值变量)
# cut()数据分组,以连续值变量分组创建新特征
bins = [0, 5, 10, 15, 20] # 切分的边界
group_names = ['A', 'B', 'C', 'D'] # 每组的标签名
df['new'] = pd.cut(df['old'], bins, labels=group_names) # new就是分组新特征
# qcut只要指定切分个数即可
df.qcut(df['年龄'],4)
数据分列(分类变量)
这个操作和Excel中的分列功能很像,在原始数据表中grade列中包含了两个层级的用户等级信息,现在我们通过数据分列将分级信息进行拆分。数据分列操作使用的是split函数,下面是具体的代码和分列后的结果。
grade_split = pd.DataFrame((x.split('-') for x in loandata.grade),
index=loandata.index,
columns=['grade','sub_grade'])
完成数据分列操作后,使用merge函数将数据匹配会原始数据表,这个操作类似Excel中的Vlookup函数的功能。通过匹配原始数据表中包括了分列后的等级信息
loandata=pd.merge(loandata,grade_split,right_index=True, left_index=True)
设置索引
# 将列转化为索引
# 将columns中的其中两列:race和sex设置索引,race为一级,sex为二级
# inplace=True 在原数据集上修改的
# 默认情况下,设置成索引的列会从DataFrame中移除, drop=False将其保留下来
adult.set_index(['race','sex'], inplace = True)
# 取消列索引设置,并自动填充索引
adult.reset_index(level=None, drop=Fasle, inplace=False)
# 索引重塑
df.stack()
df.unstack()
排序
df.b(by=['code'], ascending=False, na_position='first')
df.sort_values(by=['code', 'name'], ascending=False, na_position='first')
# 缺失值NaN默认是排在最后后的,na_position='first'设置为排在最前面
数据筛选/切片
- []
- isin
- loc
- iloc
- ix
- contains
# []只能对 行(row/index) 切片,前闭后开
df[0:3]
df[:4]
df[4:]
# where布尔查找,建立在[]基础之上
df[df["A"]>7]
# 并
df.loc[(df['petal_length']>2)&(df['petal_width']>0.3)]
# 或
df.loc[(df['petal_length']>2)|(df['petal_width']>0.3)]
# isin()
# 返回布尔值
df["A"].isin([1,2,3])
df.loc[df['sepal_length'].isin([5.8,5.1])]
# loc :根据名称Label切片
# df.loc[A,B] A是行范围,B是列范围
df.loc[:, ['petal_length','petal_width']]
df.loc[1:4, ['petal_length','petal_width']]
df.loc[['no1','no2'], ['petal_length','petal_width']]
# iloc:切位置,以序列号去切
df.iloc[1:4,:]
# ix:混切
# 名称和位置混切,但效率低,少用
df1.ix[0:3,['sepal_length','petal_width']]
# contains()模糊匹配
# 使用DataFrame模糊筛选数据(类似SQL中的LIKE)
# 使用正则表达式进行模糊匹配,*匹配0或无限次,?匹配0或1次
df_obj[df_obj['套餐'].str.contains(r'.*?语音CDMA.*')]
# 下面两句效果一致
df[df['商品名称'].str.contains("四件套")]
df[df['商品名称'].str.contains(r".*四件套.*")]
多表拼接
merge 合并
pandas.merge可根据一个或多个键将不同DataFrame中的行合并起来
# 在未指定连接键的情况下,merge会将重叠列的列名当做键
pd.merge(left, right) # 指定“on”作为连接键,left和right两个DataFrame必须同时存在“on”列,连接键也可N对N(少用)
pd.merge(left, right, on="key")
pd.merge(left, right, on=["key1", "key2"]) # 指定left的连接键为“lkey”,right的连接键为“rkey”
pd.merge(left, right, left_on="lkey", right_on="rkey") # suffixes:用于追加到重叠列名的末尾,默认为("_x", "_y")
pd.merge(left, right, on="key", suffixes=("_left", "_right")) # 指定连接方式:“inner”(默认),“left”,“right”,“outer”
pd.merge(left, right, how="outer")
多对多连接产生的是行的笛卡尔积
常用方式:连接方式为“left”,right的连接键要唯一(去除重复值),通过right的数据补全left的数据索引上的合并(可用join代替,而且join更方便)
当DataFrame的连接键位于其索引中,可以使用 left_index=True 和 right_index=True
# 索引和索引连接
pd.merge(left, right, left_index=True, right_index=True) # "key"和索引连接
pd.merge(left, right, left_on="key", right_index=True) # 层次化索引
pd.merge(left, right, left_on=["key1", "key2"], right_index=True)
join 连接
DataFrame的join实例方法,是为了方便实现索引合并
# 用left的索引和right的索引进行merge
left.join(right) # 用left的索引和right的“key”进行merge
left.join(right, on="key") # 层次化索引
left.join(right, on=["key1", "key"]) # join可以合并两张以上的表,而merge只能合并两张表
left.join([right1, right2], how="outer")
concat 轴向连接
pandas.concat可以沿着一条轴将多个表对象堆叠到一起:因为模式how模式是“outer”
# 默认 axis=0 上下拼接,列column重复的会自动合并
pd.concat([df1, df2], axis=0) # axis=1 左右拼接,行raw/index重复的会自动合并
pd.concat([df1, df2], axis=1) # 忽略df1和df2原来的index,重新给新的DataFrame设置从0开始的index
pd.concat([df1,df2], ignore_index=True)
append
使用场景:表头一致的多张表,进行连接(上下连接)
df1.append(df2).append(df3)
combin_first 数据填补
使用场景:有两张表left和right,一般要求它们的表格结构一致,数据量也一致,使用right的数据去填补left的数据缺漏
如果在同一位置left与right数据不一致,保留left的数据
df1.combin_first(df2)
数据聚合&分组运算
groupby
# 单层分组
df.groupby('区域')
# 多层分组
df.groupby(['A','B'])
# 每个分组记录的计数
df.groupby('区域').size()
>>> 区域
东莞 7528
中山 520
佛山 5632
...
dtype: int64
# 分组数
len(df.groupby('区域'))
>>> 7
aggregate
grouped = df.groupby(['A','B'])
# 对一个特征一次求得多个统计数
grouped['age'].agg([np.sum, np.mean, np.std])
# 对单一属性统计可以改列名
grouped['age'].agg({"求和":np.sum,"求平均数":np.mean})
# 对不同属性求不同的统计数
grouped.agg({'age':np.mean,'fnlwgt':np.sum})
filter
# filter()
# 过滤分组计数少于1000的分组,在把分组计数大于1000的分组整合成一个DataFrame返回
con1 = lambda s : len(s) > 1000
df1 = grouped.filter(con1)
# 过滤分组age均值小于30的分组
con2 = lambda s : s['age'].mean()>30
df2 = grouped3.filter(con2)
tansformation
# tansformation()
# 会返回一个数据集,这个数据集与group具有相同的索引以及大小 相当分组处理后合并
# 举例说明对数据集进行标准化:
zscore = lambda s : (s - s.mean())/s.std()
df = grouped.transform(zscore)
数据透视表
crosstab
# crosstab() 一般只用与计数的数据透视表
pd.crosstab(index= df['A'],
columns = [df['B'],df['C']],
margins =True,
dropn=True)
pivot/pivot_table
# Produce 'pivot' table based on 3 columns of this DataFrame.
# Uses unique values from index / columns and fills with values.
# 感觉能使用的场景很少,因为不重复
df.pivot(index, columns, values)
df.pivot_table(values=None,
index=None,
columns=None,
aggfunc='mean',
fill_value=None,
margins=False,
dropna=True,
margins_name='All')
# 需求: index 是A ,columns 是 B,C, 我要求E的平均数并且有边
pd.pivot_table(df,
values = 'E',
index = 'A',
columns = ['B','C'],
aggfunc = [np.mean,np.sum],
margins = True)
时间序列
时间格式转化
# 转化时间格式
df['time']=pd.to_datetime(df['time'])
时间索引操作
哑编码
pd.get_dummies(data,
prefix=None,
prefix_sep='_',
dummy_na=False,
columns=None,
sparse=False,
drop_first=False)
数据导出
pd.to_csv("XXX.csv",index=False)
from sqlalchemy import create_engine
engine = create_engine('mssql+pymssql://zxadmin:Zx!@#$8888@172.17.180.113/BS_KF')
pd.io.sql.to_sql(df,'payroll',engine,if_exists='append',index=False,chunksize=10000)
数据入库
# pd 1.9以后的版本,除了sqllite,均需要通过sqlalchemy来设置
from sqlalchemy import create_engine
engine = create_engine('mssql+pymssql://zxadmin:Zx!@#$8888@172.17.180.113:8000/BS_KF')
# append:如果表存在,则将数据添加到这个表的后面
# fail:如果表存在就不操作
# replace:如果存在表,删了,重建
pd.io.sql.to_sql(df,'table_name',engine,if_exists='append',index=False,chunksize=10000)
# 关闭连接
engine.dispose()
技巧
数据集概览
# 整体概况
def birdview(data):
print(data.shape)
d = {}
for col in data.columns:
if len(list(data[col].unique()))<30:
d[col]= str(list(data[col].unique()))
else:
d[col]= "too much"
r = pd.DataFrame(pd.Series(d),columns=['values'])\
.join(pd.DataFrame(data.dtypes,columns=['type']))\
.join(pd.DataFrame(data.count(),columns=['count']))\
.join(pd.DataFrame(data.isnull().sum(),columns=['isnull']))
return r.sort_values(by=['values','type',])
def catview(data):
print("定性数据概况")
for c in data.columns:
print(c)
print(dict(df[c].value_counts()))
def valueview(data):
print("定值数据概况")
return data.describe().T\
.join(pd.DataFrame(data.skew(),columns=['skew']))\
.join(pd.DataFrame(data.kurt(),columns=['kurt']))
长宽表转换
宽表转换为长表
# 方法一:先用set_index,再用stack,然后还有rename修改下列名
df.set_index(['Company','Name'], inplace = True).stack().reset_index()
# 方法二:melt
df.melt(id_vars=['Company','Name'],
var_name='Year',
value_name='Sale')
长表转换为宽表
df.pivot_table(index=['Company','Name'], columns='Year', values='Sale')
行列互换
df.T
Python模块-pandas的更多相关文章
- import pandas as pd Python安装pandas模块
在学习python过程中需要用到一个叫pandas的模块,在pycharm中安装时总是出错. 千般百度折腾还是无果,后来发现它需要安装很多依赖包.就问你气不气~ 需要手动安装啊,千万记住,这里有个py ...
- 使用Python的pandas模块、mplfinance模块、matplotlib模块绘制K线图
目录 pandas模块.mplfinance模块和matplotlib模块介绍 pandas模块 mplfinance模块和matplotlib模块 安装mplfinance模块.pandas模块和m ...
- Python利用pandas处理Excel数据的应用
Python利用pandas处理Excel数据的应用 最近迷上了高效处理数据的pandas,其实这个是用来做数据分析的,如果你是做大数据分析和测试的,那么这个是非常的有用的!!但是其实我们平时在做 ...
- 基于 Python 和 Pandas 的数据分析(4) --- 建立数据集
这一节我想对使用 Python 和 Pandas 的数据分析做一些扩展. 假设我们是亿万富翁, 我们会想要多元化地进行投资, 比如股票, 分红, 金融市场等, 那么现在我们要聚焦房地产市场, 做一些这 ...
- 基于 Python 和 Pandas 的数据分析(1)
基于 Python 和 Pandas 的数据分析(1) Pandas 是 Python 的一个模块(module), 我们将用 Python 完成接下来的数据分析的学习. Pandas 模块是一个高性 ...
- python模块大全
python模块大全2018年01月25日 13:38:55 mcj1314bb 阅读数:3049 pymatgen multidict yarl regex gvar tifffile jupyte ...
- python之pandas简单介绍及使用(一)
python之pandas简单介绍及使用(一) 一. Pandas简介1.Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据 ...
- [转]Python 模块收集
Python 模块收集 转自:http://kuanghy.github.io/2017/04/04/python-modules Python | Apr 4, 2017 | python 工具 a ...
- Python数据分析--Pandas知识点(二)
本文主要是总结学习pandas过程中用到的函数和方法, 在此记录, 防止遗忘. Python数据分析--Pandas知识点(一) 下面将是在知识点一的基础上继续总结. 13. 简单计算 新建一个数据表 ...
随机推荐
- Python2.7-tarfile
tarfile模块,读写 tar 压缩文件,包括用 gzip 或是 bz2 压缩的文件(如tar.bz2.tar.gz),一般使用 TarFile 类完成操作 1.模块方法 tarfile.is_ta ...
- Android Fragment(一)
一.为什么要引入Fragments? 自从Android 3.0中引入fragments 的概念,可以译为:碎片.片段.其上的是为了解决不同屏幕分辩率的动态和灵活UI设计.大屏幕如平板小屏幕如手机,平 ...
- Android 导入工程文件引用包出错
解决办法:将工程文件夹和引用文件夹需在同一目录下,问题解决.
- 【转】VISUAL STUDIO 2008代码指标为您节省资金
转自:https://www.geekzone.co.nz/vs2008/4773 Visual Studio 2008 Team Developer和Team Suite版本中提供的许多新功能之一是 ...
- python:'ascii' codec can't encode character
python默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错,python没办法处理非ascii编码的, 此时需要自己设置python的默认编码,一般设置为u ...
- php字符串替换的几个函数
strtr() str_replace() substr_replace() preg_replace() strtr()的用法: <?php $str = "test"; ...
- 20155308『网络对抗技术』Exp5 MSF基础应用
20155308『网络对抗技术』Exp5 MSF基础应用 一.原理与实践说明 实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻击实 ...
- AT24C02跨页写数据
AT24C02 EEPROM的写数据分为:字节写数据模式和页写数据模式:字节写就是一个地址一个数据的写,页写是连续写数据,一个地址多个数据的写,但是页写不能自动跨页,如果超出一页长度,超出的数据会覆盖 ...
- 用C++实现一个Brainfuck解释器
Brainfuck是一种极小化的计算机语言,只含有8种运算符,由于fuck在英语中是脏话,这种语言有时被称为brainfck或brainf**,甚至被简称为BF.正如它的名字所暗示,brainfuck ...
- Istio 流量治理功能原理与实战
一.负载均衡算法原理与实战 负载均衡算法(load balancing algorithm),定义了几种基本的流量分发方式,在Istio中共有4种标准负载均衡算法. •Round_Robin: 轮询算 ...