pandas_数据处理分析基本

20210405 fancy_lee

1.pandas介绍

Python Data Analysis Library 或 pandas ,是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的,
pandas是python里面分析结构化数据的工具集,基础是numpy,图像库是matplotlib
提供了大量能使我们快速便捷地处理数据的函数和方法。

2.数据结构

是由一组数据(各种NumPy数据类型),以及一组数据标签(索引)组成,不要求数据类型是相同的。可以看作是一维数组


import pandas as pd
import numpy as np

pd.Series(data,index)

s1=pd.Series(data=[3,-5,7,4],index=list('abcd'))

print(s1[0],s1['a'])

s1[0]=8

s1[s1>3]

DataFrame的单列数据为一个Series,第一列为行索引,数据列为列索引


date=pd.date_range(start='20100101',end='20100106')
date

df=pd.DataFrame(index=date,columns=list('abcd'),data=np.random.randn(6,4))

pandas提供的方法drop

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

labels 代表删除行或列的标签 必填
axis x为1 y为0
levels 标签所在的级别 int或索引名
inplace False 不对原数据生效

df1=df.drop(labels=['a','b'],axis=1,inplace=False)

df2=df.drop(labels=date[0],axis=0)

df['new']=

data.insert(2,'c','')


df.a
df['a']
df[['a','b']]

df[0:1]

head()
tail()

loc,iloc方法
loc方法是针对DataFrame索引名称的切片方法,loc使用索引名称切片,iloc使用索引切片

DataFrame.loc[行索引名称或条件, 列索引名称]
DataFrame.iloc[行索引位置, 列索引位置]

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

df1=df.loc['20100101':'20100104','a':'b']
df1=df.loc['20100101':'20100104',['a','b']]

增加条件的查询

df1=pd.DataFrame(data={'姓名':['lisa','john','cc'],'年龄':[20,14,16]},index=['a','b','c'])
df1['年龄']>15

df1[df1['年龄']>15]

df1['姓名'][df1['年龄']>15]

df1.loc[df1['年龄']>15,'姓名']
df.sort_index(axis=,ascending=)
df.sort_values(by=,ascending=)

df_index_sort=df.sort_index(axis=0,ascending=False)

df_values_sort=df.sort_values(by='a',ascending=False)

data=pd.merge(pd.merge(users,ratings),movies)

3.Pandas获取数据

read_table
read_csv 

pandas.read_table(filepath_or_buffer, sep='\t', header='infer', names=None, index_col=None, dtype=None, engine=None, nrows=None)

参数名称说明filepathstring。代表文件路径。无默认。该字符串可以是一个URL。sep接收string。代表分隔符。read_csv默认为”,”,read_table默认为制表符”[Tab]”。headerint或sequence。表示是否将某行数据作为列名。默认为infer,表示自动识别。namesarray。表示列名。默认为None。index_colint、sequence或False。表示选择哪列作为行索引,取值为sequence则代表多重索引。默认为None。dtypedict。代表写入的数据类型(列名为key,数据格式为values)。默认为None。enginec或者python。代表数据解析引擎。默认为c。nrowsint。表示读取前n行。默认为None。

注意事项:

header参数是用来指定列名的,如果是None,我们需要添加一个默认的列名。采用names设置

encoding代表文件的编码格式,常用的编码有utf-8、utf-16、gbk、gb2312、gb18030等。

DataFrame.to_csv(path_or_buf=None, sep=',', na_rep=", columns=None, header=True, index=True,index_label=None,mode='w',encoding=None)

na_rep string。代表缺失值。默认为""。

columns list。代表写出的列名。默认为None。
header boolean,代表是否将列名写出。默认为True。

index  boolean,代表是否将行名(索引)写出。默认为True。
index_labels sequence。表示行索引名。默认为None。

mode string。代表数据写入模式。默认为w。

4.pandas描述性统计分析概述

方法名称说明方法名称说明min最小值max最大值mean均值ptp极差median中位数std标准差var方差cov协方差sem标准误差mode众数quantile四分位数count非空值数目describe描述统计

describe,能够一次性得出数据框所有数值型特征的非空值数目、均值、四分位数、标准差。
cov各个维度偏离其均值的程度

  • 描述类别型特征的分布状况,可以使用频数统计表。pandas库中实现频数统计的方法为 value_counts。
  • describe支持对数据进行描述性统计,四个统计量分别为
    列非空元素的数目,
    类别的数目,
    数目最多的类别,
    数目最多类别的数目

5.pandas统计分析

Dataframe.groupby()

参数名称说明bylist,string,mapping或generator。用于确定进行分组的依据。无默认。axisint。表示操作的轴向,默认对行进行操作。默认为0。levelint或者索引名。代表标签所在级别。默认为None。as_indexboolearn。表示聚合后的聚合标签是否以DataFrame索引形式输出。默认为True。sortboolearn。表示是否对分组依据分组标签进行排序。默认为True。group_keysboolearn。表示是否显示分组标签的名称。默认为True。

用groupby方法分组后的结果并不能直接查看,而是被存在内存中,输出的是内存地址。类似Series与DataFrame结构,但是pandas提供的一种对象

GroupBy对象常用的描述性统计方法如下。

方法名称说明方法名称说明count计算分组的数目,包括缺失值。cumcount对每个分组中组员的进行标记,0至n-1。head返回每组的前n个值。size返回每组的大小。max返回每组最大值。min返回每组最小值。mean返回每组的均值。std返回每组的标准差。median返回每组的中位数。sum返回每组的和。

agg方法求统计量

.agg
func 接收list、dict、function。表示应用于每行/每列的函数。无默认
axis 接收0或1。代表操作的轴向。默认为0。

detail[['counts','amounts']].agg([np.sum,np.mean])

detail.agg({'counts':np.sum,'amounts':np.mean})

detail.agg({'counts':np.sum,'amounts':[np.mean,np.sum]})

demon


df = pd.DataFrame({'A': [1, 1, 2, 2],
                   'B': [3, 4, 3, 4],
                   'C': np.random.randn(4)})

df1=df.groupby('A').agg('min')
print(df1)

df2=df.groupby(['A','B']).agg(['min','max'])
print(df2)

df3=df.groupby('A').agg({'B':['min','max'],'C':'sum'})
print(df3)

利用pivot_table函数可以实现透视表

pands.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')

参数名称说明data接收DataFrame。表示创建表的数据。无默认。

接收字符串。用于指定想要聚合的数据字段名,默认使用全部数据。

接收string或list。表示行 分组键。默认为None。

接收string或list。表示列 分组键。默认为None。

接收functions。表示 聚合函数。默认为mean。

接收boolearn。表示汇总(Total)功能的开关,设为True后结果集中会出现名为”ALL”的行和列。默认为True。dropna接收boolearn。表示是否删掉全为NaN的列。默认为False。


pd.pivot_table(df,index="经理",values=["价格"],aggfunc=[np.sum])

pd.pivot_table(df,index=["经理","销售代表"],values=["价格"],aggfunc=np.sum)

pd.pivot_table(df,index=["经理"],columns=['销售代表'],values=["价格"],fill_value=0,aggfunc=np.sum)

pd.pivot_table(df,index=["经理","销售代表"],values=["价格"],fill_value=0,
               columns=["产品"],aggfunc=[np.sum])

pd.pivot_table(df,index=["经理"],columns=["产品"],values=["数量","价格"],fill_value=0,aggfunc={"数量":np.sum,"价格":np.mean})

交叉表是一种特殊的透视表,主要用于计算分组频数。利用pandas提供的crosstab函数可以制作交叉表

交叉表是透视表的一种

pd.crosstab()

index
columns
aggfunc
dropna
margings boolearn。默认为True。汇总(Total)功能的开关,出现名为"ALL"的行和列

demo


import pandas as pd
import numpy as np
data = pd.DataFrame({'Sample': range(1, 11), 'Gender': ['Female', 'Male', 'Female', 'Male', 'Male', 'Male', 'Female', 'Female', 'Male', 'Female'],
                    'Handedness': ['Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed']})
data

pd.pivot_table(index='Gender',columns='Handedness',data=data,values='Sample',aggfunc=len,margins=True)

pd.crosstab(index=data['Gender'],columns=data.Handedness,margins=True)

简单分析方法:(现状分析或问题定位)掌握数理统计等知识完成基础的业务数据分析,提取有价值的信息,形成有效的结论。比如:描述性统计分析,探索性数据分析

深层业务逻辑建模分析:(未来数据预测)使用数据挖掘算法中的分类、聚类、回归等方法搭建模型,分析完成复杂的数据分析工作,重点挖掘数据价值,寻找模式与规律。

6.描述性统计分析

描述性统计分析:描述性统计分析要对调查总体所有变量的有关数据做统计性描述,主要包括数据的集中趋势分析、连续型数据分布形态、类别型数据的频数分析

7.探索性统计分析

EDA(Exploratory Data Analysis)

tips:就是寻找列与列的关系

数据预处理大体分为三个步骤

1.数据清洗:数据缺失值处理 pd.notnull,差值等
2.转换数据:将字符型(对象型)量化为数值型,数据one-hot处理:逻辑回归算法需要传入的数据是数值型
3.标准化数据:对数据进行标准化处理,处理异常值

1.合并数据

将x轴或将y轴拼接以达到合并效果

pd,concat()

objs Series,DataFrame的组合。表示参与连接的pandas对象的列表的组合。无默认。

axis  0或1。表示连接的轴向,默认为0y
join inner或outer。表示其他轴向上的索引是按交集(inner)还是并集(outer)进行合并。默认为outer。

join_axes Index对象。表示用于其他n-1条轴的索引,不执行并集/交集运算。
ignore_index boolean。表示是否不保留连接轴上的索引,产生一组新索引range(total_length)。默认为False。

keys sequence。使用传递的键作为最外层来构造层次索引。加上一个层次的key来识别数据源自于哪张表
names list。生成的层次结构索引中的级别的名称。默认为None。

verify_integrity boolearn。表示是否检查结果对象新轴上的重复情况,如果发现则引发异常

当axis=1的时候,concat做横向合并 ,x轴拼接
列拼接,对行求并或交

当axis=0的时候,concat做纵向合并,y轴拼接
行拼接,对列交或并

纵向堆叠append方法

append方法也可以用于纵向合并两张表。但是append方法实现纵向表堆叠有一个前提条件,那就是两张表的列名需要完全一致。

df.append()

other DataFrame或Series。表示要添加的新数据。

ignore_index boolean。如果输入True,会对新生成的DataFrame使用新的索引(自动产生)而忽略原来数据的索引

verify_integrity boolean。如果输入True,那么当ignore_index为False时,会检查添加的数据索引是否冲突,如果冲突,则会添加失败

demo

import numpy as np
import pandas as pd

df1 = pd.DataFrame(np.ones((3,4)), columns=['a','b','c','d'])
df2 = pd.DataFrame(np.ones((3,4)), columns=['a','b','c','d'])
df3 = pd.DataFrame(np.ones((3,4)), columns=['a','b','c','d'])
print(df1)
print(df2)
print(df3)

res=pd.concat(objs=[df1,df2,df3],axis=0)
res

res=pd.concat(objs=[df1,df2,df3],axis=0,ignore_index=True)
res

df1 = pd.DataFrame(np.ones((3,4))0,columns=['a','b','c','d'], index=[1,2,3])
df2 = pd.DataFrame(np.ones((3,4))1,columns=['b','c','d','e'], index=[2,3,4])

res=pd.concat(objs=[df1,df2],axis=0,join='outer',sort=True,keys=['df1','df2'],names=['df_name','row_id'])
res

res=pd.concat(objs=[df1,df2],axis=0,join='inner',ignore_index=True)
res

df1 = pd.DataFrame(np.ones((3,4))0, columns=['a','b','c','d'])
df2 = pd.DataFrame(np.ones((3,4))1, columns=['a','b','c','d'])

df1.append(df2,ignore_index=True)

和数据库的join一样,merge函数也有左连接(left)、右连接(right)、内连接(inner)和外连接(outer)

tips
左连接,以左边的表格为参考,保留左表所有数据,再以两表中的其中一个字段作为合并的主键,可能会增加(重复),或者丢失右表的数据

内连接 交集  外连接 并集
vpandas.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)

参数名称说明left接收DataFrame或Series。表示要添加的新数据。无默认。right接收DataFrame或Series。表示要添加的新数据。无默认。。how接收inner,outer,left,right。表示数据的连接方式。默认为inner。on接收string或sequence。表示两个数据合并的主键(必须一致)。默认为None。left_on接收string或sequence。表示left参数接收数据用于合并的主键。默认为None。right_on接收string或sequence。表示right参数接收数据用于合并的主键。默认为None。left_index接收boolean。表示是否将left参数接收数据的index作为连接主键。默认为False。right_index接收boolean。表示是否将right参数接收数据的index作为连接主键。默认为False。sort接收boolean。表示是否根据连接键对合并后的数据进行排序。默认为False。

import pandas as pd
import numpy as np

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                             'A': ['A0', 'A1', 'A2', 'A3'],
                             'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K4'],
                              'C': ['C0', 'C1', 'C2', 'C3'],
                              'D': ['D0', 'D1', 'D2', 'D3']})
left
right

res=pd.merge(left,right,on='key',how='left')
res

left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3'],
                   'key': ['K0', 'K1', 'K0', 'K1']})

right = pd.DataFrame({'C': ['C0', 'C1'],
                      'D': ['D0', 'D1']},
                    index=['K0', 'K1'])
result = pd.merge(left, right, left_on='key', right_index=True, how='left', sort=True)
result

left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                    'B': ['B0', 'B1', 'B2']},
                     index=['K0', 'K1', 'K2'])

right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
                      'D': ['D0', 'D2', 'D3']},
                        index=['K0', 'K2', 'K3'])
pd.merge(left,right,how= 'left',left_index=True,right_index=True)

2.数据清洗

利用isnull或notnull找到缺失值

df.isnull()

pandas中提供了简便的删除缺失值的方法dropna,该方法既可以删除观测记录,亦可以删除特征(当缺失值超过25%)

pandas.DataFrame.dropna(self, axis=0, how='any', thresh=None, subset=None, inplace=False)

axis 0或1。表示轴向,0为删除观测记录(行)
how 接收特定string。表示删除的形式。
   any表示只要有缺失值存在就执行删除操作。
   all表示当且仅当全部为缺失值时执行删除操作。默认为any。

subset array数据。表示进行去重的列∕行。默认为None,表示所有列/行。

inplace boolean。表示是否在原表上进行操作
  • 替换法是指用一个特定的值替换缺失值。
  • 缺失值所在特征为 数值型时,通常利用其均值、中位数和众数等描述其集中趋势的统计量来代替缺失值。(固定值,最近临插补,回归,插值函数)
  • 缺失值所在特征为 类别型时,则选择使用 众数来替换缺失值

pandas库中提供了缺失值替换的方法名为fillna

pandas.DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None)

value scalar,dict,Series或者DataFrame。表示用来替换缺失值的值

method string。backfill或bfill表示使用下一个非缺失值填补缺失值。pad或ffill表示使用上一个非缺失值填补缺失值。默认为None。

limit int。表示填补缺失值个数上限,超过则不进行填补。默认为None。

demo

import pandas as pd
import numpy as np

dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates, columns=['A','B','C','D'])
df.iloc[0,1] = np.nan
df.iloc[1,2] = np.nan

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

df2=df.fillna(value=0)
df2

df['B']=df['B'].fillna(df['B'].mean())
df

df['C']=df['C'].fillna(df['C'].mean())
df

df3=df.isnull()
df3

df5=df.isnull().sum(axis=1)
df5

df5.sum()

scipy提供了插值算法可以通过一组散点得到一个符合一定规律插值器函数。这样当我们给插值器函数更多未知x,插值函数将会返回相应的y用于填补缺失值。
scipy提供的插值方法如下:

import scipy.interpolate as si
func = si.interp1d(
    离散水平坐标,
    离散垂直坐标,
    kind=插值算法(缺省为线性插值)
)

demon

import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as si
x = [30, 40, 50, 60, 65]
y = [100, 120, 135, 155, 170]
plt.scatter(x, y)
xs = np.linspace(min(x), max(x), 200)

linear = si.interp1d(x, y, kind='linear')
print(linear(45))
ys = linear(xs)
plt.plot(xs, ys,color='r')
plt.show()
import numpy as np

from scipy.interpolate import interp1d
import matplotlib.pyplot as plt

x = np.linspace(0, 10, num=11, endpoint=True)
y = np.cos(-x ** 2 / 9.0)

f = interp1d(x, y)
f2 = interp1d(x, y, kind='cubic')

xnew = np.linspace(0, 10, num=41, endpoint=True)

plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
plt.legend(['data', 'linear', 'cubic'], loc='best')
plt.show()

3.标准化数据

1.当数据取值范围较大
2.消除单位带来的影响
3.加快算法模型速度

将样本转换到 0-1之间
数据的整体分布情况并不会随离差标准化而发生改变,原先取值较大的数据,在做完离差标准化后的值依旧较大。
当数据和最小值相等的时候,通过离差标准化可以发现数据变为0。

符合正态分布时使用

demon

import numpy as np
import pandas as pd
np.random.seed(1)
df = pd.DataFrame(np.random.randn(4, 4)  4 + 3)
df

df_norm=(df-df.min())/(df.max()-df.min())
df_norm

df_norm1=(df-df.mean())/(df.std())
df_norm1

4.转换数据

部分的算法模型都要求输入的特征为数值型,但实际数据中特征的类型不一定只有数值型,还会存在相当一部分的类别型,这部分的特征需要经过哑变量处理才可以放入模型之中,(类别型数据编码化)

pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None)

参数名称说明data接收array、DataFrame或者Series。表示需要哑变量处理的数据。无默认。prefix_sep接收string。表示前缀的连接符。默认为’_’。dummy_na接收boolean。表示是否为Nan值添加一列。默认为False。columns接收类似list的数据。表示DataFrame中需要编码的列名。默认为None,表示对所有object和category类型进行编码。prefix接收string、string的列表或者string的dict。表示哑变量化后列名的前缀。默认为None。

哑变量处理特点

虚拟变量,也叫哑变量和离散特征编码,可用来表示分类变量、非数量因素可能产生的影响。

离散特征的编码分为两种情况:

  • 离散特征的取值之间没有大小的意义,比如color:[red,green],那么就使用one-hot编码
  • 离散特征的取值有大小的意义,比如size:[X,XL,XXL],那么就使用数值的映射{X:1,XL:2,XXL:3}
  • 对于一个类别型特征,若其取值有m个,则经过哑变量处理后就变成了m个二元特征,并且这些特征互斥,每次只有一个激活,这使得数据变得稀疏。
  • 对类别型特征进行哑变量处理主要解决了部分算法模型无法处理类别型数据的问题,这在一定程度上起到了扩充特征的作用。由于数据变成了稀疏矩阵的形式,因此也加速了算法模型的运算速度。

demo

import pandas as pd
df = pd.DataFrame([
            ['green','M','10.2','class1'],
            ['red','L','13.5','class2'],
            ['blue','XL','15.3','class1'],
           ])
df.columns = ['color','size','prize','class label']
df
df.info()
size_mapping={'XL':3,'L':2,'M':1}
df['size']=df['size'].map(size_mapping)
df
class_mapping={label:idx for idx,label in enumerate(set(df['class label']))}
class_mapping
df['class label']=df['class label'].map(class_mapping)
df
pd.get_dummies(df)

知识点补充: enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

seasons=['Spring','Summer','Fall','Winter']
list(enumerate(seasons))
list(enumerate(seasons,start=2))

i=0
seq=['one','two','three']
for element in seq:
    print (i,seq[i])
    i+=1

seq=['one','two','three']
for i,element in enumerate(seq):
    print(i,element)
  • 某些模型算法,特别是某些分类算法如ID3决策树算法和Apriori算法等,要求数据是离散的,此时就需要将连续型特征(数值型)变换成离散型特征(类别型)。
  • 连续特征的离散化就是在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表落在每个子区间中的数据值。
  • 因此离散化涉及两个子任务,即确定分类数以及如何将连续型数据映射到这些类别型数据上。
pandas.cut(x, bins, right=True, labels=None, retbins=False)

参数名称说明x接收数组或Series。代表需要进行离散化处理的数据。无默认。bins接收int,list,array,tuple。若为int,代表离散化后的类别数目;

若为序列类型的数据,则表示进行切分的区间,每两个数间隔为一个区间。无默认。right接收boolean。代表右侧是否为 闭区间。默认为True。labels代表离散化后的各个类别名称retbins接收boolean。代表是否返回区间标签。默认为False。

import pandas as pd
ages=[20,22,34,56,34,12,9,43,23,18,45]
bins=[5,10,15,20,25,30,40,45,50,60]
cut_data=pd.cut(x=ages,bins=bins)
cut_data
cut_data.value_counts().plot(kind='barh')

5.数据规约

属性合并来创建新属性维数,或者直接删除不相关的属性来减少数据维数
目的是寻找最小的属性子集并确保新数据子集的概率分布尽可能的接近原来的数据集概率分布

指的是通过选择替代的,较小的数据来减少数据量

  • 有参数:使用模型来评估数据,只存放参数,不存放实际数据
    eg:线性回归/多元回归
  • 无参数:存放实际数据, 直方图/聚类/抽样 (1)直方图。如一连串的数据,通过绘制直方图(R中用hist()函数绘制直方图),分为”315″、”1628″、”29~41″三个范围。
    (2)聚类。将对象划分为簇,使一个簇中的对象相互”相似”,而与其他簇中的对象”相异”,用数据的簇替换实际数据。
    (3)抽样。有放回/无放回

Original: https://blog.csdn.net/weixin_44402083/article/details/115443476
Author: 李默默404
Title: pandas_数据处理分析基本

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/741604/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球