2018-06-04 12:37:59 jz20171222 阅读数 540
  • Python数据分析实战-Pandas

    深度学习、机器学习和数据分析必须用pandas。pandas是在python直接流行的数据处理框架。可以说,如果不会使用pandas,就谈不上会用python做数据分析。本课程会使用奥林匹克一个真实的数据作为实验数据,从初级到各种pandas的常用操作,到常用的数据可视化,让你在短的时间内掌握好pandas,轻松愉快的玩转数据分析。

    2359 人正在学习 去看看 阿勒拉哈

Pandas数据处理

现有一数据集Data.out,通过Pandas提取数据并绘制曲线。提取内容下图所示:



工具:Pycharm,Python2.7,Pandas,Numpy,matplotlib


#导入所需要库

import pandas as pd
import numpy as np
import re
import matplotlib as mpl
import matplotlib.pyplot as plt

#使用pandas.read.fwf()读取定宽列格式数据

Data = pd.read_fwf('Data.out')

#使用to.csv()保存DataFrame文件以利于观察和查看

Data.to_csv('CreatData.txt', sep=',')
List_all = [] #定义所有情况的集合
List_need=[]#定义所需的列表
#提取==data==01-set==data==02-set==data==03-set对应的行数
for i in range(Data.ix[:,0].size):
    if re.search('==',str(Data.ix[[i]].values[0][0])) !=None:
        List_all.append(i)

#定义所需的字符列表
List_Tab_need = ['02-set']
#提取字符列表对应的行数
for i in range(Data.ix[:, 0].size):
    for j in range(len(List_Tab_need)):
        if re.search(List_Tab_need[j], str(Data.ix[[i]].values[0][0])) != None:
            List_need.append(i)
List_and=[i for i in range(len(List_all)) if List_all[i] in List_need]
#提取x,y并绘制曲线
def y_x(List_all):
    y=[]#定义y空列表
    x=[]#定义x空列表
    a=List_all[List_and[0]]+5
    b=List_all[List_and[0]+1]-1
    Taking_x_rst=Data.iloc[a:b,0]
    for i in range((Taking_x_rst.size/2)):
        a0=a+2*i
        #y数据
        y.append(float(Data.iloc[a0,0].split()[0]))
    for i in range((Taking_x_rst.size/2)):
        b0=a+1+2*i
        if len(Data.iloc[b0,0].split())==5:
            x.append(float(Data.iloc[b0,0].split()[3].split('/')[1]))
        else:
            x.append(float(Data.iloc[b0,0].split()[4]))
    ny=np.array(y)
    dx=np.array([1/i for i in x])
    #绘制曲线
    plt.figure(facecolor="w",figsize=(3,4))
    plt.plot(dx,ny,"--",label=u"y-x",color="red",linewidth=3)
    plt.title(u"*_y-x_*",fontsize=15)
    plt.xlabel(u"x",fontsize=20)
    plt.ylabel(u"y",fontsize=20)
    plt.xlim((0,max(dx)))
    plt.ylim((0,ny[0]))
    plt.legend()
    plt.savefig(u"y-x")#保存图片
    plt.show()
y_x(List_all)


代码地址:https://github.com/jz20170904/Pandas-data/tree/master

2018-12-04 15:56:43 qq_40195360 阅读数 783
  • Python数据分析实战-Pandas

    深度学习、机器学习和数据分析必须用pandas。pandas是在python直接流行的数据处理框架。可以说,如果不会使用pandas,就谈不上会用python做数据分析。本课程会使用奥林匹克一个真实的数据作为实验数据,从初级到各种pandas的常用操作,到常用的数据可视化,让你在短的时间内掌握好pandas,轻松愉快的玩转数据分析。

    2359 人正在学习 去看看 阿勒拉哈

前言

  • 对于二维平面数据来说,pandas无疑是数据处理和数据分析的好帮手,接下来就细细的演示和讲解一下,一些关于pandas的操作,希望能对你有所帮助。

这里主要利用pandas从六个方面来对数据进行操作:

1 导入数据

自我生成数据

pandas 有两个常用的数据结构:Series 和 DataFrame,可以用来生成你想要的数组型对象。

pd.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
    
pd.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)

外部加载数据

但是,在一般的数据处理分析中,往往自我生成数据情况较少,更多的是导入数据。pandas提供了一些用于将表格型数据读取为DataFrame对象的函数。
这里导入本次需要的用到的数据(该数据来自天猫爬取的网页数据,有兴趣的可以自己去爬取,这里只是暂做示例):

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

data = pd.read_excel("E:/data/tianmao_phone.xlsx")

表1对我们常用的文件格式进行了总结,其中pd.read_csv()pd.read_excel()可能会是你今后用得最多的。
在这里插入图片描述
这些pandas的解析函数参数较为复杂,具体了解可以在pandas官网上自行查阅,或者可以再Jupyter Notebook 中采用help(pd.read_excel)命令查阅。

注:这里使用的都是小规模的数据(500万以下),而在现实生活中的数据有时往往跟为复杂(动辄几个G到TB),pandas在读取的时候往往就会用到chunsize等参数(可以传入大小)分块读取。
但是,其效率也是低下,所以建议大数据还是用一些适合它的的工具(数据库等),没有最好的工具,只有最适合的工具。

2 审阅数据

在成功导入数据以后,需要对数据进行审阅,目的是,了解数据结构、类型、大小等情况。方便理解数据和为后续处理分析打下基础。

1.查看前5行(默认前5行,你也可以在括号里输入你想要的行数):

data.head()

在这里插入图片描述

2.查看倒数5行:

data.tail()

3.查看维度信息:

data.shape

4.查看每一列的数据格式:

data.dtypes

5.查看数据表基本信息(维度、列名称、数据格式、所占空间等):

data.info()

在这里插入图片描述

6.查看某一列具体信息:

#两种处理效果一样
data['月销量']

data.月销量

7.也可以按索引提取单行或多行数值:

#提取第4行
data.iloc[4]

#提取到第4行
data.iloc[0:4]

#提取所有行,0到4列(也可以反过来)
data.iloc[:,0:4]

#提取第0、2、4行,第3、4列
data.iloc[[0,2,4].[3,4]]

注:数据的选取较为灵活,方法也较多,诸如:data["你要选取的列名称"]data.loc[]data.iloc[]data.ix[]等等。具体可以上官网了解一下他们的区别和作用,这里就不再继续详述了。

8.将数据进行排序

#按销量的大小进行排序,只取前8行
data.sort_values(by=['累计评价'],ascending=False).iloc[:8,:]

在这里插入图片描述

#查看类别信息
count_class = pd.value_counts(data['店铺名称'],sort=True).sort_index()
print(count_class)

9.查看基本的统计信息(最大值、最小值、平均值、中位值、四分位值、标准差等):

data.describe()

3 数据预处理

说完对表中的数据进行简单的查看,下面进行对数据进行的最关键操作:数据预处理

(1) 数据集成

由于我的数据较为规整,不需要合并和拼接,这里只是简单介绍一下原理。

1.pandas.merge可根据一个或多个键将不同DataFrame中的行连接起来。SQL或其他关系型数据库的用户对此应该会比较熟悉,因为它实现的就是数据库的join操作。

pandas.merge(left, right, how='inner', on=None, 
left_on=None, right_on=None, left_index=False, right_index=False,
 sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)

该函数主要用于通过一个或多个键将两个数据集的行连接起来,类似于 SQL 中的 JOIN。典型应用场景是,针对同一个主键存在两张包含不同字段的表,现在我们想把他们整合到一张表里。在此典型情况下,结果集的行数并没有增加,列数则为两个元数据的列数和减去连接键的数量。

2.pandas.concat该方法相当于数据库中的全连接(UNION ALL),可以指定按某个轴进行连接,也可以指定连接的方式join(outer,inner 只有这两种)。与数据库不同的是concat不会去重,要达到去重的效果可以使用drop_duplicates方法。

pandas.concat(objs, axis=0, join='outer',
 join_axes=None, ignore_index=False, keys=None,
levels=None, names=None,verify_integrity=False, sort=None, copy=True)

轴向连接 pd.concat()只是单纯的把两个表拼在一起,这个过程也被称作连接(concatenation)。这个函数的关键参数应该是 axis,用于指定连接的轴向。在默认的 axis=0 情况下,pd.concat([data1,data2]) 函数的效果与 data1.append(data2) 是相同的;而在 axis=1 的情况下,pd.concat([data1,data2],axis=1) 的效果与pd.merge(data1,data2,left_index=True,right_index=True,how='outer') 是相同的。可以理解为 concat 函数使用索引作为“连接键”。

3.join方法提供了一个简便的方法用于将两个DataFrame中的不同的列索引合并成为一个DataFrame。

DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)

其中参数的意义与merge方法基本相同,只是join方法默认为左外连接how=left
4.DataFrame.combine_first(other) 可以将重复数据拼接在一起,用一个对象中的值填充另一个对象中的缺失值。

5.update.如果要用一张表中的数据来更新另一张表的数据则可以用update来实现

DataFrame.update(other, join='left', overwrite=True, filter_func=None, raise_conflict=False)

注:使用combine_first会只更新左表的nan值。而update则会更新左表的所有能在右表中找到的值(两表位置相对应)。

具体了解可以在pandas官网上自行查阅,或者可以再Jupyter Notebook 中采用help()命令查阅。

(2) 数据清洗

数据整理

1.字符串处理

原始数据中,有很多字符串类型的数据,不便于分析,利用字符串函数对数据进行处理。

#将“收藏”字符串中的数值型数据取出来
data['收藏']=data['收藏'].str.extract('(\d+)')

#同理“库存”只要数据
data['库存']=data['库存'].str.extract('(\d+)')

#同理“天猫积分”只要数据
data['天猫积分']=data['天猫积分'].str.extract('(\d+)')

#“现价”中含有区间值,进行拆分,并取最低价
data['现价']=data['现价'].str.split('-',expand=True)[0]

#同理,“原价”拆分,与“现价”保持一致
data['原价']=data['原价'].str.split('-',expand=True)[0]

2.数据类型处理

将处理完的字符串数据,转换成有利于后续分析的数据。

#时间序列处理
data['当前时间']=pd.to_datetime(data['当前时间'],format='%Y%m%d')

#将时间序列设置为索引并按照索引进行排序
data=data.set_index(data['当前时间']).sort_index()

#由于月销量数据带有字符串,所以需要将字符串替换,并最终转化为数值型
data['月销量']=data['月销量'].str.replace('万','0000')
data['月销量']=data['月销量'].str.replace('+','')
data['月销量']=data['月销量'].str.replace('.','').astype(np.float64)

#其他数据类型处理

data['现价']=data['现价'].astype(np.float64) 

data['原价']=data['原价'].astype(np.float64) 

data['收藏']=data['收藏'].astype(np.float64) 

data['库存']=data['库存'].astype(np.float64) 

data['天猫积分']=data['天猫积分'].astype(np.float64) 

注:在处理数据进行格式转换时,有时object无法转换成int64或者float64,这时就需要先处理内部格式,再进行转换。如:
data['orginal_shop_price']=data['orginal_shop_price'].str.replace(",",'').astype(np.float64)

缺失值处理:

1.查找缺失值。看那些列存在缺失值:

data.isnull().any()

2.定位缺失值。将含有缺失值的行筛选出来:

#筛选出任何含有缺失值的数据
data[data.isnull().values==True]

#统计某一列缺失值的数量
data['现价'].isnull().value_counts()

#筛选出某一列含有缺失值的数据
data[data['原价'].isnull().values==True]

3.删除缺失值:

data.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)`

#删除月销量中的缺失值
data.dropna(axis=0,subset=["月销量"])

可以利用subset和thresh参数来删除你需要删除的缺失值,inplace则表示是否在原表上替代。

4.填充缺失值:
固定值填充:

data.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
#利用月销量的均值来对NA值进行填充
data["月销量"].fillna(data["月销量"].mean())

#利用月销量的中位数来对NA值进行填充
data["月销量"].fillna(data["月销量"].median())

#对于一些商品的现价和原价没有的数据,可采用现价填充原价,原价填充现价。
data["现价"]=data["现价"].fillna(data["原价"])
data["原价"]=data["原价"].fillna(data["现价"])

当然,缺失值的处理方法远不止这几种,这里只是简单的介绍一般操作,还有其他更高级的操作,比如:随机森林插值、拉格朗日插值、牛顿插值等等。针对这些高难度的插值方法,有兴趣可以自我去了解了解。

重复值处理

定位重复值:

#找出"店铺名称"存在重复的数据
data[data.duplicated(subset=["店铺名称"], keep='first')]

删除重复值:

#删除“店铺名称”存在重复的数据
data.drop_duplicates(subset=["店铺名称"], keep='first', inplace=False)

异常值处理:

在进行异常值处理之前,需先进行异常值检验,比较常用的有两种方法:

  1. 数据服从正态分布,采用3σ原则。
  2. 数据不服从正太分布,采用箱线图检验。
    3σ原则:
#插入一列three_sigma又来表示是否是异常值
data['three_sigma'] = data['月销量'].transform( lambda x: (x.mean()-3*x.std()>x)|(x.mean()+3*x.std()<x))

#筛选出目标变量的异常值
data[data['three_sigma']==True]

#保留正常的数据
correct_data=data[data['three_sigma']==False]

箱线图处理异常值:

#定义一个下限
lower = data['月销量'].quantile(0.25)-1.5*(data['月销量'].quantile(0.75)-data['月销量'].quantile(0.25))

#定义一个上限
upper = data['月销量'].quantile(0.25)+1.5*(data['月销量'].quantile(0.75)-data['月销量'].quantile(0.25))

#重新加入一列,用于判断
data['qutlier'] = (data['月销量'] < lower) | (data['月销量'] > upper) 

#筛选异常数据
data[data['qutlier'] ==True]

#过滤掉异常数据
qutlier_data=data[data['qutlier'] ==False]

细心的你可能会发现,采用两种方法来处理异常数据的结果往往是不同的,箱线图法更为严格(有兴趣的话,你可以去了解了解其中的原理)。

多余行/多余列删除

data.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')

该操作主要用于不需要的行(默认删除行)或者列进行删除,从而有利于数据精简。

(3) 数据变换
数据变换主要有以下几点内容:

1.简单函数变换。例如对数据开方、平方、取对数、倒数、差分、指数等。目的是为了后续分析提供想要的数据和方便分析(根据实际情况而定)。

#由于“累计评价”的值太大,我们新增一列对“累计评价”取对数处理
data['对数_累计评价']=np.sqrt(data['累计评价'])

#插入一列,计算“优惠力度”
data['优惠力度']=data1['现价']/data1['原价']

2.数据标准化。数据标准化是为了消除数据的量纲影响,为后续许多算法分析必要条件。常见的标准化方法很多,这里只是简单介绍一下:
Min-Max标准化

#使不使用函数,根据你的理解都可以,这里使用函数
data['标准化月销量']=data.月销量.transform(lambda x : (x-x.min())/(x.max()-x.min()))

Z-score标准化法

data['Z_月销量']=data['月销量'].transform(lambda x : (x-x.mean())/x.std())

3.数据离散化处理。连续值经常需要离散化或者分箱,方便数据的展示和理解,以及结果的可视化。比如最常见就是日常生活中对年龄的离散化,将年龄分为:幼儿、儿童、青年、中年、老年等。

#新增一列,将月销量划分成10个等级
data['data_cut']=pd.cut(data['月销量'],bins=10,labels=[1,2,3,4,5,6,7,8,9,10])

#新增一列,将月销量划分成10个等级
data['data_qcut']=pd.qcut(data['月销量'],q=10,labels=[1,2,3,4,5,6,7,8,9,10])

这两种都是对数据进行离散化,但通过结果仔细一看,你会发现,这两者的结果是不同的。说简单点就是,一个是等距分箱,一个是等频分享(分位数分箱),往往后者更常用。

(4) 数据精简
数据精简在数据分析和数据挖掘中至关重要,数据挖掘和分析的往往是海量数据,其海量特征主要体现在两个方面:第一,样本量庞大;第二,变量个数较多。海量数据无疑会影响建模的效率,为此主要的应对措施有:
1.压缩样本量。主要是指随机抽样
2.简约变量值。主要是指离散化处理
3.变量降维。主要是将许多变量用少数变量来分析(诸如因子分析等)

变量的离散化处理前面已经介绍,这里从随机抽样入手。关于变量降维,后续关于算法的学习在具体介绍。

#随机不重复抽取100行数据样本
data.sample(n=100)

关于随机抽样函数如下:

sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)

n和frac作用是相同的,n是抽样个数,frac是抽样比例(浮点数);
replace:是否为有放回抽样,取replace=True时为有放回抽样;
weights这个是每个样本的权重,具体可以看官方文档说明。

4 数据分析

终于来到了数据分析环节,前面所做的工作全是为了数据分析和数据可视化做准备。这里本文只是进行一些简单的数据分析,关于模型啊,算法啊……这些,这里不做介绍,在掌握这些简单的分析之后,可以去理解更高深的分析方法。
(1) 描述性分析

1.集中趋势
表示数据集中趋势的指标有:平均值、中位数、众数、第一四分位数和第三四分位数。

#通过定义一个函数,来查看数据的集中趋势
def f(x):
    return pd.DataFrame([x.mean(),x.median(),x.mode(),x.quantile(0.25),x.quantile(0.75)],
    index=['mean','median','mode','Q1','Q3'])

#调用函数
f(data['月销量'])

2.离散程度
表示数据离散程度的有:方差,标准差,极差,四分位间距。

#通过定义一个函数,来查看数据的离散程度
def k(x):
    return pd.DataFrame([x.var(),x.std(),x.max()-x.min(),x.quantile(0.75)-x.quantile(0.25)],
                        index=['var','std','range','IQR'])

#调用函数
k(data['现价']

2.分布形态
表示数据分布的有:偏度和峰度。

def g(x):
    return pd.DataFrame([x.skew(),x.kurt()],
                        index=['skew','kurt'])

(2) 相关性分析
研究两个或两个以上随机变量之间相互依存关系的方向和密切程度的方法。线性相关关系主要采用皮尔逊(Pearson)相关系数r来度量连续变量之间线性相关强度;r>0,线性正相关;r<0,线性负相关;r=0,两个变量之间不存在线性关系,但是,并不代表两个变量之间不存在任何关系,有可能是非线性相关。

#相关系数矩阵
data.corr()

#协差阵
data.cov()

#任意两列相关系数
data['月销量'].corr(data['累计评价']

#因变量与所有变量的相关性
data.corrwith(data['月销量'])

5 pandas数据可视化

数据可视化的作用很多,而最常用的一般有两种功能:其一是对原始数据的探索性分析(EDA),其二是对结果数据的数据分析结果呈现。

data_plot=data.groupby(by="店铺名称").agg({'月销量':sum})

#下面的代码与上面的效果等同

data.groupby(by='店铺名称')['月销量'].sum()

在这里插入图片描述

data_plot.unstack().sort_values(ascending=False).plot(kind='bar', figsize=(20, 5))

在这里插入图片描述

这里不再过多的讲解pandas可视化,因为pandas中的数据可视化已经可以满足我们大部分的要求了,也就省下了我们很多自己使用 如 matplotlib 来数据可视化的工作。所以我把pandas可视化放在下一篇博客单独来讲。

附上地址:pandas可视化

2019-08-12 14:40:40 weixin_44451032 阅读数 93
  • Python数据分析实战-Pandas

    深度学习、机器学习和数据分析必须用pandas。pandas是在python直接流行的数据处理框架。可以说,如果不会使用pandas,就谈不上会用python做数据分析。本课程会使用奥林匹克一个真实的数据作为实验数据,从初级到各种pandas的常用操作,到常用的数据可视化,让你在短的时间内掌握好pandas,轻松愉快的玩转数据分析。

    2359 人正在学习 去看看 阿勒拉哈

Pandas基本常用数据处理操作——第二节

以下是本次实验使用的数据,如需要数据表学习的请留言
在这里插入图片描述

读取数据并显示

#本节使用的数据表示kaggle泰坦尼克拯救比赛的数据
#导入模块  读取数据
import pandas as pd
import numpy as np
titanic = pd.read_csv('titanic_train.csv')
#显示数据  仅显示前10行
titanic.head(10)
#passengerid  表示游客id
#survived  表示是否被救 1表示成功被救   0表示没有获救
#Pclass  表示船舱等级
#name  游客名字
#sex  表示游客性别
#age  游客年龄、
#sibsp  表示家里兄弟姐妹的个数
#parch   表示家里父母和孩子的个数
#ticket  船票编码
#fare  船票
#cabin  船舱位置
#embarked  登船地点
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
5 6 0 3 Moran, Mr. James male NaN 0 0 330877 8.4583 NaN Q
6 7 0 1 McCarthy, Mr. Timothy J male 54.0 0 0 17463 51.8625 E46 S
7 8 0 3 Palsson, Master. Gosta Leonard male 2.0 3 1 349909 21.0750 NaN S
8 9 1 3 Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) female 27.0 0 2 347742 11.1333 NaN S
9 10 1 2 Nasser, Mrs. Nicholas (Adele Achem) female 14.0 1 0 237736 30.0708 NaN C

可以看到cabin中有很多 NaN值 Pandas用NaN值表示缺失值 可以使用isnull这个函数来判断某一个值是否是缺失值

#查看Age这一列有多少个缺失值
age = titanic['Age']
age_null_number = 0
for this_age in age:
    if pd.isnull(this_age):
        age_null_number += 1
print(age_null_number)
177

当存在缺失值的时候要计算某一项数据时不能包括缺失值,否则最后结果也是缺失值

#计算所有游客的年龄
avg_age = sum(titanic['Age']) / len(titanic['Age'])
avg_age  #因为游客中有的人的年龄确实为nan所以计算时会返回nan
nan

想要得到所有游客的平均年龄,必须去掉nan值,这时类似在numpy中用的逻辑索引可以通过判断是否为nan值返回的逻辑值索引

real_age = titanic['Age'][pd.isnull(titanic["Age"]) == False]
avg_real_age = sum(real_age) / len(real_age)
avg_real_age
29.69911764705882

显然通过上述方法完全可以得到平均年龄,但是比较繁琐,pandas提供了mean函数可以直接忽略nan值进行计算

mean_age = titanic['Age'].mean()
mean_age
29.69911764705882

还可以分别计算三种等级船舱的平均价格

#mean fare for every pclass
passenger_classes = [1,2,3]
fare_by_class = {}
for this_class in passenger_classes:
    this_class_mean_fare = titanic['Fare'][(titanic['Pclass'] == this_class)].mean()
    fare_by_class[this_class] = this_class_mean_fare
fare_by_class
{1: 84.1546875, 2: 20.662183152173913, 3: 13.675550101832993}

上述方法显然可以计算出每种船舱的平均价格 但是pandas提供了一个pivot_table函数可以直接计算

#index 表示索引值 最后的计算结果按照index值分组
#values   表示想要进行计算的列
# aggfunc  表示计算的方法  默认计算均值
fare_by_class = titanic.pivot_table(index='Pclass',values='Fare',aggfunc=np.average)
fare_by_class
Fare
Pclass
1 84.154687
2 20.662183
3 13.675550

计算三种等级的船舱每种船舱平均被救的人数

every_pclass_survived = titanic.pivot_table(index='Pclass',values='Survived')
every_pclass_survived
Survived
Pclass
1 0.629630
2 0.472826
3 0.242363

计算每种等级船舱游客的平均年龄

every_pclass_avg_age = titanic.pivot_table(index='Pclass',values='Age')
every_pclass_avg_age
Age
Pclass
1 38.233441
2 29.877630
3 25.140620

计算三种登船地点的收钱总数和被救人数

ports_embarked = titanic.pivot_table(index='Embarked',values=['Fare','Survived'],aggfunc=np.sum)
ports_embarked
Fare Survived
Embarked
C 10072.2962 93
Q 1022.2543 30
S 17439.3988 217

分别计算三种登船地点的总人数

every_port_passenger_number = titanic.pivot_table(index='Embarked',values='PassengerId',aggfunc=np.count_nonzero)
every_port_passenger_number
PassengerId
Embarked
C 168
Q 77
S 644

计算三种登船地点的获救率

every_port_survived_rate = ports_embarked['Survived'] / every_port_passenger_number['PassengerId']
every_port_survived_rate
Embarked
C    0.553571
Q    0.389610
S    0.336957
dtype: float64

对缺失数据进行处理

#dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
# axis : {0 or 'index', 1 or 'columns'}, default 0    Determine if rows or columns which contain missing values ar eremoved.
#how : {'any', 'all'}, default 'any'  Determine if row or column is removed from DataFrame, when we have at least one NA or all NA.
#'any' : If any NA values are present, drop that row or column.
# 'all' : If all values are NA, drop that row or column.
#subset : array-like, optional   Labels along other axis to consider, e.g. if you are dropping rows
#int, optional    Require that many non-NA values.
#inplace : bool, default False   If True, do operation inplace and return None.
titanic[0:5]
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S

默认axis = 0,how = ‘any’ 使用drop去掉含有nan值的行

titanic.dropna().head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
6 7 0 1 McCarthy, Mr. Timothy J male 54.0 0 0 17463 51.8625 E46 S
10 11 1 3 Sandstrom, Miss. Marguerite Rut female 4.0 1 1 PP 9549 16.7000 G6 S
11 12 1 1 Bonnell, Miss. Elizabeth female 58.0 0 0 113783 26.5500 C103 S

可以看到Cabin有很多缺失值 去掉Cabin这一列

titanic.drop(axis= 1,labels='Cabin').head()  #只显示前五行
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 S

去掉所有含有nan的列 但是这在实际操作中是很少用到的

titanic.dropna(axis=1).head()
PassengerId Survived Pclass Name Sex SibSp Parch Ticket Fare
0 1 0 3 Braund, Mr. Owen Harris male 1 0 A/5 21171 7.2500
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 1 0 PC 17599 71.2833
2 3 1 3 Heikkinen, Miss. Laina female 0 0 STON/O2. 3101282 7.9250
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 1 0 113803 53.1000
4 5 0 3 Allen, Mr. William Henry male 0 0 373450 8.0500

去掉age和sex两列只要有一个为缺失值的行

new_titantic = titanic.dropna(axis=0,subset=['Age','Sex'])
new_titantic.head(10)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
6 7 0 1 McCarthy, Mr. Timothy J male 54.0 0 0 17463 51.8625 E46 S
7 8 0 3 Palsson, Master. Gosta Leonard male 2.0 3 1 349909 21.0750 NaN S
8 9 1 3 Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) female 27.0 0 2 347742 11.1333 NaN S
9 10 1 2 Nasser, Mrs. Nicholas (Adele Achem) female 14.0 1 0 237736 30.0708 NaN C
10 11 1 3 Sandstrom, Miss. Marguerite Rut female 4.0 1 1 PP 9549 16.7000 G6 S

去掉age和sex都为为缺失值的行

new_titantic = titanic.dropna(axis=0,subset=['Age','Sex'],how='all')
new_titantic.head(10)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
5 6 0 3 Moran, Mr. James male NaN 0 0 330877 8.4583 NaN Q
6 7 0 1 McCarthy, Mr. Timothy J male 54.0 0 0 17463 51.8625 E46 S
7 8 0 3 Palsson, Master. Gosta Leonard male 2.0 3 1 349909 21.0750 NaN S
8 9 1 3 Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) female 27.0 0 2 347742 11.1333 NaN S
9 10 1 2 Nasser, Mrs. Nicholas (Adele Achem) female 14.0 1 0 237736 30.0708 NaN C

定位csv文件中的某一个值

row_index_3_name = titanic.loc[3,"Name"]
row_index_3_name
'Futrelle, Mrs. Jacques Heath (Lily May Peel)'
titanic['Name'][3]
'Futrelle, Mrs. Jacques Heath (Lily May Peel)'
titanic.loc[3]['Name']
'Futrelle, Mrs. Jacques Heath (Lily May Peel)'

对年龄这一列排序

titanic.sort_values('Age',ascending=False).head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
630 631 1 1 Barkworth, Mr. Algernon Henry Wilson male 80.0 0 0 27042 30.0000 A23 S
851 852 0 3 Svensson, Mr. Johan male 74.0 0 0 347060 7.7750 NaN S
493 494 0 1 Artagaveytia, Mr. Ramon male 71.0 0 0 PC 17609 49.5042 NaN C
96 97 0 1 Goldschmidt, Mr. George B male 71.0 0 0 PC 17754 34.6542 A5 C
116 117 0 3 Connors, Mr. Patrick male 70.5 0 0 370369 7.7500 NaN Q

排序后NaN值默认排在最后

titanic.sort_values('Age',ascending=False).tail(5)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
859 860 0 3 Razi, Mr. Raihed male NaN 0 0 2629 7.2292 NaN C
863 864 0 3 Sage, Miss. Dorothy Edith "Dolly" female NaN 8 2 CA. 2343 69.5500 NaN S
868 869 0 3 van Melkebeke, Mr. Philemon male NaN 0 0 345777 9.5000 NaN S
878 879 0 3 Laleff, Mr. Kristo male NaN 0 0 349217 7.8958 NaN S
888 889 0 3 Johnston, Miss. Catherine Helen "Carrie" female NaN 1 2 W./C. 6607 23.4500 NaN S

排序之后重置索引值 由于drop = False实际上是重新生成了一列索引值

titanic.sort_values('Age',ascending=False).reset_index(drop = False).head()
index PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 630 631 1 1 Barkworth, Mr. Algernon Henry Wilson male 80.0 0 0 27042 30.0000 A23 S
1 851 852 0 3 Svensson, Mr. Johan male 74.0 0 0 347060 7.7750 NaN S
2 493 494 0 1 Artagaveytia, Mr. Ramon male 71.0 0 0 PC 17609 49.5042 NaN C
3 96 97 0 1 Goldschmidt, Mr. George B male 71.0 0 0 PC 17754 34.6542 A5 C
4 116 117 0 3 Connors, Mr. Patrick male 70.5 0 0 370369 7.7500 NaN Q

排序之后重置索引值 drop = True 丢弃原来的索引值

titanic.sort_values('Age',ascending=False).reset_index(drop=True).head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 631 1 1 Barkworth, Mr. Algernon Henry Wilson male 80.0 0 0 27042 30.0000 A23 S
1 852 0 3 Svensson, Mr. Johan male 74.0 0 0 347060 7.7750 NaN S
2 494 0 1 Artagaveytia, Mr. Ramon male 71.0 0 0 PC 17609 49.5042 NaN C
3 97 0 1 Goldschmidt, Mr. George B male 71.0 0 0 PC 17754 34.6542 A5 C
4 117 0 3 Connors, Mr. Patrick male 70.5 0 0 370369 7.7500 NaN Q
2019-07-28 16:20:44 me_to_007 阅读数 32
  • Python数据分析实战-Pandas

    深度学习、机器学习和数据分析必须用pandas。pandas是在python直接流行的数据处理框架。可以说,如果不会使用pandas,就谈不上会用python做数据分析。本课程会使用奥林匹克一个真实的数据作为实验数据,从初级到各种pandas的常用操作,到常用的数据可视化,让你在短的时间内掌握好pandas,轻松愉快的玩转数据分析。

    2359 人正在学习 去看看 阿勒拉哈
  • 线下处理文件,文件上千万、亿级别,直接用pandas方法处理几番爆内存,可以用pandas分块读取再做整合处理,但每次都码上这段分块处理的code很麻烦,这里也是希望在做一些数据过滤使用装饰器上能够提供一些思路,欢迎大家提出更好的建议…
import pandas as pd
import time
import numpy as np

chunks = []     # 分块处理后的文件合并列表

def outer(read_fun=pd.read_csv,use_time=True,use_filter=True):
    '''
    :param read_fun: pandas分块读取文件读物方法,比如:pd.read_csv
    :param use_time: Boolean类型,是否使用计时装饰,默认为True
    :param use_filter: Boolean类型,是否使用过滤装饰,默认为True
    '''
    def reader(fun):
        def inner(*args,**kwargs):
            if use_time:
                start = time.time()
            if use_filter:
	            global chunks
	            chunk_size = kwargs['chunk_size'] if 'chunk_size' in kwargs else 2000000
	            if 'chunk_size' in kwargs:
	                del kwargs['chunk_size']        #read_fun里没有chunk_size这个参数,传进去会报错
	            print('chunk_size:{}'.format(chunk_size))
	            loop = True
            	reader = read_fun(args[1],iterator=True,**kwargs)       # 函数在类里,args[0]是类对象,这里传入args[1]
                global df
                i = 0
                rows = 0
                while loop:
                    try:
                        df = reader.get_chunk(chunk_size)
                        fun(*args,**kwargs)
                        i += 1
                        rows += chunk_size
                        if use_time:
                            sr_format = '第{cnt}阶段数据已经处理完,已经处理行数:{row},累计耗时{usetime:.2f}s'
                            print(sr_format.format(cnt=i,row=rows,usetime=time.time()-start))
                    except StopIteration:
                        loop = False
                        print('文件读取完毕,正在合并中,请稍等......')
                df = pd.concat(chunks,ignore_index=False)
                del chunks
                sr_format = '文件已经处理完成,df行数:{shape}\n'
                if use_time:
                    sr_format += '累计耗时{usetime:.2f}s......\n'
                print(sr_format.format(shape=df.shape[0],usetime=time.time()-start),df.head())
                return df
            else:
                fun(*args,**kwargs)
                if use_time:
                    print(fun.__name__,'累计耗时:{usetime:.2f}s...'.format(usetime=time.time()-start))
        return inner
    return reader


class Operate():
    def __init__(self):
        pass

    @outer(pd.read_csv)
    def data_filter(self,decorate_file_path,feature_name,filter_content,**kwargs):
        '''
        一个简单的单字段筛选函数
        :param decorate_file_path: 装饰器分块读取文件路径,使用装饰必传参数
        :param feature_name: 要筛选的字段特征名称
        :param filter_content: 该字段要筛选的内容
        :param kwargs:
        1. 其他包括每次读取chunk_size块大小,供装饰函数read函数关键字参数;
        2. 除了chunk_size参数,其他关键字参数请使用read_fun内在参数,避免函数定义没有关键字参数,出现其他参数报错;
        '''
        global chunks
        global df
        df = df[df[feature_name]==filter_content]
        chunks.append(df)
        time.sleep(np.random.random()*2)        # 模拟计算延时

    @outer(pd.read_csv)
    def other_fun(self):
        '''其他处理方法'''
        pass

    def file_out(self,df,out_path,**kwargs):
        df.to_csv(out_path,index=False,encoding='utf_8_sig',**kwargs)
        print('file is output to {}'.format(out_path))

	@outer(use_filter=False)		# 只使用了计时装饰
    def use_time_test(self,num):
        i = 0
        for each in range(num):
            i += each
        print('return:{}'.format(i))



if __name__ == '__main__':
    m = Operate()
    #df = m.data_filter(r"D:\桌面\qq.txt",'qq_id',88888888,sep='\t',encoding='utf_8',chunk_size=3)
    #m.file_out(df,'d:/桌面/test.csv')
    m.use_time_test(100000000)

pandas其他文章:
DataFrame创建、导出、文件读取、索引切片
pandas文件读取,导出、索引切片、一些常用的参数注释

2019-11-16 18:54:54 mocas_wang 阅读数 21
  • Python数据分析实战-Pandas

    深度学习、机器学习和数据分析必须用pandas。pandas是在python直接流行的数据处理框架。可以说,如果不会使用pandas,就谈不上会用python做数据分析。本课程会使用奥林匹克一个真实的数据作为实验数据,从初级到各种pandas的常用操作,到常用的数据可视化,让你在短的时间内掌握好pandas,轻松愉快的玩转数据分析。

    2359 人正在学习 去看看 阿勒拉哈

对于数据处理的基本操作使用,自己使用总结。

首先导入模块库

import pandas as pd
import numpy as np
from pandas import Series,DataFrame

读取csv文件

data_train=pd.read_csv("/home/mocas/kaggle/titanic/train.csv",index_col=0) ##乘客数据导入

index_col=0代表将第一列作为index,如果不加index_col这个,则采用默认的index

存储csv文件
1.

submission = pd.DataFrame({ 'PassengerId': test_df['PassengerId'],'Survived': predictions })
submission.to_csv("submission.csv", index=False)
# index参数是否写入行names键

2.

RF = test[['PassengerId','Survived']].set_index('PassengerId')
RF.to_csv('RF1.csv')

从dict生成:
 

pd.DataFrame.from_dict(df, orient='index')

选择数据

df['A']  通过列name(键)选择列
df[['A', 'B']]  通过list选择列
df[0:3]  通过隐含的序列(index所在行值)选择行
df['20130102':'20130104']   通过行index(键)选择行
dataset[(dataset['Sex'] == i) & (dataset['Pclass'] == j+1)]['Age'] ###布尔运算选择数据,以其他列为条件筛选数据,注意做布尔运算时最好将每个运算用括号括起来,像以下这种就会容易出问题:dataset[dataset['TARGET'].notnull() & dataset['need_pre']!=1 ]

显示数据类型

加不加[],生成的类型是不同的
type(data["A1"])
pandas.core.series.Series
type(data[["A1"]])
pandas.core.frame.DataFrame
all_df['MSSubClass'].dtypes

loc切片的使用

dataset.loc[ dataset.Age.isnull(),'BB']  //age是null的数据中选择BB列,isnull是选取空缺的意思
train_df.loc[:, ['Age*Class', 'Age', 'Pclass']].head(10)
dataset.loc[ EID,'Age']  # //根据index(注意这个是index的取值,而不是index所在行)选取列Age单元数据

iloc:
iloc是选择DataFrame第几行第几列(类似于数组,数值下标从0开始)

df.iloc[3:5,0:2]
df.iloc[1:3,:]
df.iat[1,1]

Multi-index索引

result_df = df.loc[(df.index.get_level_values('A') > 1.7) & (df.index.get_level_values('B') < 666)]

result_df
Out[537]: 
          C
A   B      
3.3 222  43
    333  59
5.5 333  56
df.query('0 < A < 4 and 150 < B < 400') 
Out[17]:                                                                    
          C                                                                 
A   B                                                                       
1.1 222  40                                                                 
3.3 222  20                                                                 
    333  11
x = df.reset_index()
In [16]: x.loc[(x.B>=111.0)&(x.B<=500.0)].set_index(['A','B'])
Out[16]: 
          C
A   B      
1.1 111  81
    222  45
3.3 222  98
    333  13
5.5 333  89

循环行数据:

for i, row in colTypes.iterrows():
# i为dataFrame的index,row为一行数据

使用另一series作为dataframe的筛选条件

import numpy as np
import pandas as pd
df = pd.DataFrame({ 'A' : [1,2,3,4],
                     'B' : [4,5,6,7]
                  })  
a = pd.Series([1,2,3,1])
# 对series进行筛选
(a==1).sum()
>>>2
# 对dataframe进行筛选
df[a==1].sum(0)
>>>
A     5
B    11
dtype: int64

判断是否在序列中筛选:

meta_df = meta_df[meta_df['asin'].isin( reviews_df['asin'].unique() )]
new_rate = new_rate[~new_rate['reviewerID'].isin(low_index)]  # not in,取反

计算数据

重复数值个数统计:

Series.value_counts() //统计重复重现的数据的个数。返回以数据作为key,以重复个数为value的对象。
X[c].value_counts().index[0] //最多的那个数

中值计算:

Series.median() //计算某个轴的中值

计算均值和偏差

age_mean = guess_df.mean()
# 计算均值
age_std = guess_df.std()
# 计算标准差

计算众值

# freq_port = train_df.Embarked.dropna().mode()[0]##这是计算除了空缺行之外的众数
# mode返回出现最多的数据,可能出现多个,因此返回数组

其他:
方法 说明
count 非NA值得数量
describe 针对series或各dataframe列计算汇总统计
min max 计算最小值和最大值
argmin,argmax 计算能够获取到最小值和最大值的索引位置(整数)

much_nuclei = df_img['nuclei'].argmax()
plt.imshow(imgs[much_nuclei])

idxmin , idxmax     计算获取到最小值和最大值索引值

df.idxmax()   //按列
df.idxmax(axis=1)  //按行

quantile        计算样本的分位数(0到1)
sum           值得总和

df.sum()   //按列求和
df.sum(axis=1)  //按行求和

mean          值得平均数

df.mean(axis=1) //按行求和,注意,如果存在Nan值会忽略,如果整个都为nan,则取nan
df.mean(axis=1, skipna = False) //禁止忽略nan值

median 值的算数中位数
mad 根据平均值计算平均绝对离差
var 样本值得方差
std 样本值得标准差
skew 样本值得偏度(三阶矩)
kurt 样本值的峰度(四阶矩)
cumsum 样本值的累计和,累计累积,也就是说从开始位置到当前位置的总和

df.cumsum()   //按列求累积和,如果当前位置为nan,直接返回nan,如果不是,而前面某个位置是,则忽略前面位置的nan
df.cumsum(axis=1)  //按行求累积和

cummin,cummax 样本值的累计最大值和累计最小值
cumprod 样本值的累计积
diff 计算一阶差分(对时间序列很有用)
pct_change 计算百分数变化
isin 判断series,dataframe数据是否在另一个变量其中
缺失值处理

性质:
np.nan == np.nan
>>> False
 
np.isnan(np.nan)
>>> True
 
np.nan is None
>>> False
 
type(np.nan)
>>> float
检测:
np.isnan(df)
pd.isnull(df)

方法 说明
count 非NA值得数量
dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值得容忍度
fillna 用指定值或插值方法(如ffill或bfill)填充确实数据
isnull 返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值/NA,该对象的类型与源类型一样
notnull isnull的否定式
存在三种方法来完善连续数字特征:
1、简单方式:在中值和标准偏差间产生一个随机数
2、准确方式:通过相关特征猜测缺失值
3、联合1、2基于特征组合,在中值和偏差间产生一个随机数

显示缺失值行列:

train_cat[train_cat.isnull().values==True]

判断某列是否包含nan:

df.isnull().any() # 判断列是否有 NaN
df.isnull().all()  # 判断列是否全部为NaN

删除缺失行:

df.dropna(axis=0, how='any', inplace=True)

缺失值填充:

dataset['E'] = dataset['E'].fillna(f)

# 对缺失值处进行填充0,参数value可为 scalar, dict, Series, 或者DataFrame,但不能是list;Series应用于每个index,DataFrame应用于每个列。如果不在dict/Series/DataFrame中,将不会被填充

清除空值:.dropna()

dataset.loc[ (dataset.Age.isnull()) & (dataset.Sex == i) & (dataset.Pclass == j+1),'Age'] = guess_ages[i,j]
# 多条件填充

方法1:

for dataset in full_data:
    age_avg 	   = dataset['Age'].mean()
    age_std 	   = dataset['Age'].std()
    age_null_count = dataset['Age'].isnull().sum()
    
    age_null_random_list = np.random.randint(age_avg - age_std, age_avg + age_std, size=age_null_count)
    dataset['Age'][np.isnan(dataset['Age'])] = age_null_random_list
    dataset['Age'] = dataset['Age'].astype(int)

方法2:

# 生成一个空数组来存储Age的猜测值:
        # guess_ages = np.zeros((2,3))
        # guess_ages
# 遍历Sex和Pclass来猜测Age猜测值:
        # for dataset in combine:
        #     for i in range(0, 2):
        #         for j in range(0, 3):
        #             guess_df = dataset[(dataset['Sex'] == i) & (dataset['Pclass'] == j+1)]['Age'].dropna()
        # 根据相关特征值Pclass,Sex选取数据并除空值
                #     age_mean = guess_df.mean()
                # 计算均值
                #     age_std = guess_df.std()
                # 计算标准差
                #     age_guess = rnd.uniform(age_mean - age_std, age_mean + age_std)
				# 产生随机值
                #     age_guess = guess_df.median()
				# 或计算中值
                #     Convert random age float to nearest .5 age
                #     guess_ages[i,j] = int( age_guess/0.5 + 0.5 ) * 0.5   
for i in range(0, 2):
      for j in range(0, 3):
            dataset.loc[ (dataset.Age.isnull()) & (dataset.Sex == i) & (dataset.Pclass == j+1),'Age'] = guess_ages[i,j]
            # 赋值
            dataset['Age'] = dataset['Age'].astype(int)

填充众值:

# freq_port = train_df.Embarked.dropna().mode()[0]
# mode返回出现最多的数据,可能出现多个,因此返回数组
# 填充:
# for dataset in combine:
#     dataset['E'] = dataset['E'].fillna(freq_port)

查看数据

查看键和值:

train_data = pd.read_csv('train.csv')
# 查看数据的行键index(index.values)、列键columns(columns.values)、值values
print(train_data.index)
print(train_data.index.values)

查看数据统计:

train_data.info()
# 主要统计有各列键非空数据数量(便于后面填充空值)、各列数据类型、及数据类型统计(一般object表示字符串对象数量)。

print(train_data.describe())
# 默认统计数值型数据每列数据平均值,标准差,最大值,最小值,25%,50%,75%比例。
print(train_data.describe(include=['O']))
# 统计字符串型数据的总数,取不同值数量,频率最高的取值。其中include参数是结果数据类型白名单,O代表object类型,可用info中输出类型筛选。

print("Before", train_data.shape)
# 数据行数和列数

查看部分数据内容:

# 查看前五条和后五条数据,大致了解数据内容
print(train_data.head())
print(train_data.tail())
# 选取三条数据
data_train.sample(3)

排序:

features.sort_values(by='EID', ascending=True)
features.sort_index(axis=1, ascending=True)
python原生排序list和dict
sorted([wifi for wifi in line[5]], key=lambda x:int(x[1]), reverse=True)[:5]  // 默认从小到大
sorted(dict.items(),key=lambda x:x[1],reverse=True)[0][0]
sorted(L, cmp=lambda x,y:cmp(x[1],y[1])) //x,y代表前后两个元素

输出格式控制:

pandas dataframe数据全部输出,数据太多也不用省略号表示。
pd.set_option('display.max_columns',None)
或者
with option_context('display.max_rows', 10, 'display.max_columns', 5):

某列字符长度统计

lens = train.comment_text.str.len()
lens.mean(), lens.std(), lens.max()
print('mean text len:',train["comment_text"].str.count('\S+').mean())
print('max text len:',train["comment_text"].str.count('\S+').max())

分析数据相关性

groupby数据

train_data[['Pclass','Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived',ascending=False)
# 选取数据中两列,以Pclass分组,计算每个分组内平均值,最后根据Survived平均值降序排列。其中as_index=False不以Pclass做结果行键。

分组后,可以通过size()分组内数据数量,sum()分组内数据和,count()分组内:

df = DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randn(5),'data2':np.random.randn(5)})  
df  
#[Out]#       data1     data2 key1 key2  
#[Out]# 0  0.439801  1.582861    a  one  
#[Out]# 1 -1.388267 -0.603653    a  two  
#[Out]# 2 -0.514400 -0.826736    b  one  
#[Out]# 3 -1.487224 -0.192404    b  two  
#[Out]# 4  2.169966  0.074715    a  one
group2 = df.groupby(['key1','key2'])
group2.size()   
#[Out]# key1  key2  
#[Out]# a     one     2     //注意size返回的对象2,1,1,1没有列键
#[Out]#       two     1  
#[Out]# b     one     1  
#[Out]#       two     1  
#[Out]# dtype: int64  
group2.count()  
#[Out]#            data1  data2    
#[Out]# key1 key2                
#[Out]# a    one       2      2    //注意count返回的对象2,1,1,1有列键data1,data2
#[Out]#      two       1      1  
#[Out]# b    one       1      1  
#[Out]#      two       1      1
group2.sum()
		                data1	data2
key1	key2		
a	    one	          0.222249	1.188488
        two	          0.627373	0.406101
b	    one	         -2.527461	0.267850
        two	         -0.594238	-0.137129 
自定义组内统计函数:
BRA_CLOSE_DECADE = branch2[['EID', 'B_ENDYEAR']].groupby('EID').agg(lambda df:df[df['B_ENDYEAR']>2007].count())
分组后循环:
for reviewerID, hist in reviews_df.groupby('reviewerID'):
  pos_list = hist['asin'].tolist()

crosstab数据:

pd.crosstab(train_data['Title'], train_data['Sex'])
# 分别以Title(Mrs,Mr等)为行,Sex(female,male)为例,计算出现频数。观察二者的对应关系。

Pivot数据:

impute_grps = data.pivot_table(values=["LoanAmount"], index=["Gender","Married","Self_Employed"], aggfunc=np.mean)

协方差cov():表示线性相关的方向,取值正无穷到负无穷。协方差为正值,说明一个变量变大另一个变量也变大;协方差取负值,说明一个变量变大另一个变量变小,取0说明两个变量咩有相关关系。
相关系数corr():不仅表示线性相关的方向,还表示线性相关的程度,取值[-1,1]。也就是说,相关系数为正值,说明一个变量变大另一个变量也变大;取负值说明一个变量变大另一个变量变小,取0说明两个变量没有相关关系。同时,相关系数的绝对值越接近1,线性关系越显著。
corrwith():计算DataFrame的列(axis=0,默认)或行(axis=1)跟另外一个Series或DataFrame之间的相关系数。

##求相关性协方差矩阵
train_corr=train.drop('PassengerId',axis=1).corr()

删除数据

print(df.drop(0,axis=0)) #删除行,注意原数据不变,返回一个新数据
print(df.drop(['col1'],axis=1,inplace=True)) #删除列,inplace=True表示直接在原数据修改而不新建对象

合并数据

对于不同列名,但是内容相同时,可以先修改表的列名。
concat:

相同字段的表首尾相接

result = pd.concat([df1, df2, df3], keys=['x', 'y', 'z']) //keys给合并的表来源加一个辨识号

注意多张表concat后可能会出现index重复情况,这是最好使用reset_index重新组织下index。

result.reset_index(drop=True)
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
       keys=None, levels=None, names=None, verify_integrity=False)

append方式:

# append方式
result = df1.append([df2, df3])  //将df2,df3追加到df1后返回
# [官方合并教程](http://pandas.pydata.org/pandas-docs/stable/merging.html#)

merge方式:
merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=(’_x’, ‘_y’), copy=True, indicator=False)
merge方式用于通过一个或多个键将两个数据集的行连接起来,类似于 SQL 中的 JOIN
on=None 用于显示指定列名(键名),如果该列在两个对象上的列名不同,则可以通过 left_on=None, right_on=None 来分别指定。或者想直接使用行索引作为连接键的话,就将left_index=False, right_index=False 设为 True。如果没有指定且其他参数也未指定则以两个DataFrame的列名交集做为连接键.
how=‘inner’ 参数指的是当左右两个对象中存在不重合的键时,取结果的方式:inner 代表交集;outer 代表并集;left 和 right 分别为取一边。
suffixes=(’_x’,’_y’) 指的是当左右对象中存在除连接键外的同名列时,结果集中的区分方式,可以各加一个小尾巴。
对于多对多连接,结果采用的是行的笛卡尔积。
 

# merge方式
# 其中how取值 : {‘left’, ‘right’, ‘outer’, ‘inner’}, default ‘inner’类似于SQL中 left outer join,right outer join, full outer join,inner join
>>> A              >>> B
    lkey value         rkey value
0   foo  1         0   foo  5
1   bar  2         1   bar  6
2   baz  3         2   qux  7
3   foo  4         3   bar  8
>>> A.merge(B, left_on='lkey', right_on='rkey', how='outer')
   lkey  value_x  rkey  value_y
0  foo   1        foo   5
1  foo   4        foo   5
2  bar   2        bar   6
3  bar   2        bar   8
4  baz   3        NaN   NaN
5  NaN   NaN      qux   7

join方式:
其中参数的意义与merge方法基本相同,只是join方法默认为左外连接how=left。默认按索引合并,可以合并相同或相似的索引。主要用于索引上的合并

join(self, other, on=None, how='left', lsuffix='', rsuffix='',sort=False): 

修改数据

从数据中提取数据:

dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False)
# 左边dataset['Title']为DataFrame添加一列,右边dataset.Name取出DataFrame的name列,然后对于该Series里的string匹配正则,返回匹配到的正则子集。[官方api](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.str.extract.html)
# 对列使用函数处理
meta_df['categories'] = meta_df['categories'].map(lambda x: x[-1][-1])
data['sum_Times']=data['Times'].groupby(['userID']).cumsum()     //统计单个userid组内到当前行之前的所有time和

替换数据:

dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
dataset['Title'].replace('Ms', 'Miss')
#将一列中数据Ms替换Miss,[详解](https://jingyan.baidu.com/article/454316ab4d0e64f7a6c03a41.html)

将分类数据数值化:

title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
for dataset in combine:
     dataset['Title'] = dataset['Title'].map(title_mapping)
# dataset['Sex'] = dataset['Sex'].map( {'female': 1, 'male': 0} ).astype(int)

转成矩阵:

big_X_imputed[0:train_df.shape[0]].values()  //将DataFrame对象转成numpy矩阵

将连续值分成几部分

# 自动
pd.cut(np.array([.2, 1.4, 2.5, 6.2, 9.7, 2.1]), 3,
           labels=["good","medium","bad"])
[good, good, good, medium, bad, good]
# 手动,一般手动前先自动分析一波。
# train_df['AgeBand'] = pd.cut(train_df['Age'], 5)
# train_df[['AgeBand', 'Survived']].groupby(['AgeBand'], as_index=False).mean().sort_values(by='AgeBand', ascending=True)
# 手动区分
# for dataset in combine:    
#     dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0
#     dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1

对每一行或每一列应用函数:

def num_missing(x):
  return sum(x.isnull())
#应用列:
print data.apply(num_missing, axis=0)
#应用行:
print data.apply(num_missing, axis=1).head()
def get_title(name):
	title_search = re.search(' ([A-Za-z]+)\.', name)
	# If the title exists, extract and return it.
	if title_search:
		return title_search.group(1)
	return ""

for dataset in full_data:
    dataset['Title'] = dataset['Name'].apply(get_title)
df.Cabin = df.Cabin.apply(lambda x: x[0])

将字符型数据转成数值型数值:

from sklearn import preprocessing
def encode_features(df_train, df_test):
    features = ['Fare', 'Cabin', 'Age', 'Sex', 'Lname', 'NamePrefix']
    df_combined = pd.concat([df_train[features], df_test[features]])
    
    for feature in features:
        le = preprocessing.LabelEncoder()
        le = le.fit(df_combined[feature])
        df_train[feature] = le.transform(df_train[feature])
        df_test[feature] = le.transform(df_test[feature])
    return df_train, df_test
    
data_train, data_test = encode_features(data_train, data_test)

除去离群点:
通过画图如果发现数据中出现一些离群点,应将其除去,使用pandas布尔运算即可:

train = train[abs(train['length'])<10]

categorial无序特征哑编码one-hot:
星期为无序特征,如果该特征有三种取值:星期一、星期二、星期三,那么可用三维向量分别表示(1,0,0)(0,1,0)(0,0,1)。使用pd.get_dummies(),如果特征取值过多就应根据数据分布规律将不重要的几个取值归为一类。
 

train_test = pd.get_dummies(train_test,columns = ['SibSp','Parch','SibSp_Parch'])
train_test = pd.get_dummies(train_test,columns=["Embarked"])

去重相同行

alter.duplicated()   //返回每行是否重复的bool值,frame.duplicated(['state'])可选择指定列进行查重。
alter.duplicated().value_counts()
alter2 = alter.drop_duplicates()  //除去相同行,注意返回新数据,而不是在旧有的上面修改
df.drop_duplicates(subset='column A', keep='last') //根据特定列去重,且保留最后一个

修改index名,列键名:

df.columns = ['a', 'b', 'c', 'd', 'e']
df.columns = df.columns.str.strip('$')
df.columns = df.columns.map(lambda x:x[1:])
df.rename(columns=('$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}, inplace=True) 
df.rename(columns=lambda x:x.replace('$',''), inplace=True)
investFeature.index.rename('EID', inplace=True)

列转index、index转列:

df.set_index('date', inplace=True)
df['index'] = df.index
df.reset_index(level=0, inplace=True)
df.reset_index(level=['tick', 'obs'])
df['si_name'] = df.index.get_level_values('si_name') # where si_name is the name of the subindex.

删除index

df_load.reset_index(inplace=True)
del df_load['index']

合并列名不同的列:
先修改列名

train_cat = train[[0,1,2,3,4]]
col = train_cat.columns
for i in range(5,20,4):
    tem = train[[0,i,i+1,i+2,i+3]]
    tem.columns = col
    train_cat = pd.concat([train_cat,tem])
train_cat.head()

设置一列类型:

df[[column]] = df[[column]].astype(str)

apply返回series数据:
这样组合成的仍然是dataframe类型

def mer(x):
    sss = []
    for i,line in x.iterrows():
        sss.extend([line[1],line['pre']])
    return pd.Series(sss)
merged = sub_cat.groupby([0]).apply(mer)

根据键值和列名合并:

save.merge(merged, left_on=['a'], right_index=True)

groupby后筛选数据:
使用filter或transform

np.random.seed(130)
df=pd.DataFrame(np.random.randint(3, size=(10,2)), columns=['item_id_copy','sales_quantity'])
print (df)
   item_id_copy  sales_quantity
0             1               1
1             1               2
2             2               1
3             0               1
4             2               0
5             2               0
6             0               1
7             1               2
8             1               2
9             1               2

df1 = df.groupby('item_id_copy').filter(lambda x: len(x["asin"].unique()) >= 4)
print (df1)
   item_id_copy  sales_quantity
0             1               1
1             1               2
7             1               2
8             1               2
9             1               2

df1 = df[df.groupby('item_id_copy')['sales_quantity'].transform('size') >= 4]
print (df1)
   item_id_copy  sales_quantity
0             1               1
1             1               2
7             1               2
8             1               2
9             1               2

pandas进行one-hot编码:

import pandas as pd
df = pd.DataFrame([  
            ['green' , 'A'],   
            ['red'   , 'B'],   
            ['blue'  , 'A']])  
df.columns = ['color',  'class'] 
df = pd.get_dummies(df)

apply返回多列:

def myfunc1(row):
    C = row['A'] + 10
    D = row['A'] + 50
    return pd.Series([C, D])

df[['C', 'D']] = df.apply(myfunc1 ,axis=1)
def sizes(s):    
    return locale.format("%.1f", s / 1024.0, grouping=True) + ' KB', \
        locale.format("%.1f", s / 1024.0 ** 2, grouping=True) + ' MB', \
        locale.format("%.1f", s / 1024.0 ** 3, grouping=True) + ' GB'
df_test['size_kb'],  df_test['size_mb'], df_test['size_gb'] = zip(*df_test['size'].apply(sizes))

按列最大最小值归一化

In [11]: df
Out[11]:
    a    b
A  14  103
B  90  107
C  90  110
D  96  114
E  91  114

In [12]: df -= df.min()

In [13]: df /= df.max() 

In [14]: df
Out[14]:
          a         b
A  0.000000  0.000000
B  0.926829  0.363636
C  0.926829  0.636364
D  1.000000  1.000000
E  0.939024  1.000000

判断一列数据是不是类型混合:

sorted(sad["size"].unique())

'<' not supported between instances of 'str' and 'float'

对df的某一行的某些值进行修改:

aad.loc[aad["type"]==2,"cdate"] = aad.loc[aad["type"]==2,"adid"].map(lambda x: cdate_map[x] if x in cdate_map.keys() else -1)

groupby 后提取前多少数据,并生成pandas

orgin = reviews_map.sort_values(["reviewerID","unixReviewTime"]).groupby("reviewerID",group_keys=False)
print(orgin.get_group(1))
history = orgin.apply(lambda df: df[:-2])
ads = orgin.apply(lambda df: df[-2:])

 

 

 

 

 

 

 

 

 

没有更多推荐了,返回首页