【Python】数据清洗之黑白双侠——numpy&pandas库

  我们分别看看numpy和pandas在数据处理中都有哪些突出的优缺点,不过大部分内容我会直接插入代码块,在代码块中进行解释。

Numpy

  numpy库有比python基础函数更高级的多维数组数值计算与处理的方法及函数。

###1  一维数组
import numpy as np
#dir(np)#查看有哪些下属

# 创建一维数组
a=np.array([1,2,3,4])
#a[1:3]

np.array(range(1,11,5))

np.arange(1,11,1)#与range 的区别
np.arange(10,0,-0.9)#左包含右不包含

np.linspace(0,9,3,endpoint=True)#生成一个数组,分组数据  endpoint是否包含结束值

###2  二维数组
np.array([[1,2,3],
          [4,5,6]])
np.array([["张三","男",23],["张三","女",18]],
         dtype=object)#输入的数据类型 dtype 尽可能的一致,行列整洁

###3  数组属性
a=np.array([1,2,3])
b=np.array([[1,2,3],
         [4,5,6]])

a.ndim
b.ndim

a.shape
b.shape

a.size
#b.size

a.dtype
b.dtype

a.itemsize#每个元素占的字节
b.itemsize#每个元素占的字节

b.itemsize*b.size

###4  缺失值问题
np.nan,None 的区别

###5  特殊数组的 快速生成
np.zeros((3,4))#生成全0 数组
np.zeros(5)
np.ones((4,4))
np.eye(5)
np.diag([1,2,3,4])#对角线矩阵
np.full((2,3),'zgl')#自定义元素数组
np.full((2,3),np.array([1,2,3]))#
np.empty((2,1))#随机元素填充 一般不用此函数来生成数组

x = np.arange(6).reshape(2,3)
x=np.array([[1,2,np.nan],[2,np.nan,4]])
np.argwhere(np.isnan(x))#获取缺失值的位置  只适用于 np.nan 数值型

###6  随机数组的生成
np.random.seed(100)#设定随机数种子
np.random.rand(3,4)#(0,1)间的3行4列的随机数组
np.random.random(10)
np.random.random((3,4))

np.random.uniform(10,50,(3,4))#间的3行4列的随机数组
np.random.randn(3,4)# N  ~  (0,1)间的3行4列的随机数组  标准正太分布
np.random.randint(3,10,(3,4))#(0,1)间的3行4列的随机数  整数
np.random.choice(3,10,2)

###7  数组排序
a=np.array([1,3,0,5])#返回变量值索引
np.argsort(a)

np.sort(a)#返回值
b=np.array([[1,3,5],[2,1,3],[0,5,1]])
b

np.argsort(b,axis=0)#默认按列排序
np.argsort(b,axis=1)
np.sort(b,axis=1)#每行(列)排序
np.sort(b,axis=0)  

b=np.array([[1,5,3],[2,1,3],[0,5,1]],dtype=object)
b

b1=sorted(b,key=lambda x:x[2],reverse=True) #与numpy 的区别
b1


students = np.array([['john', 'A', 15],
                     ['jane', 'B', 2],
                     ['dave', 'B', 10]],dtype=object)
students
# 按年龄排序 
#sorted(students, key=lambda s: s[2], reverse=True)       # 按降序


sorted(students, key=lambda x: x[2])     

###8  重塑数组
np.arange(12).reshape(3,4)
np.arange(6).reshape(1,-1)
np.arange(6).reshape(-2,2)
np.arange(12).reshape(3,-1)
a.ravel(order=True)

a=np.array([[1,4],[3,4]])
np.tile(a,3)
a.ravel()

###9  数组索引
a1=np.array([["张三","男",23],["李四","女",180],["李红","女",170]])
a1

a1[0:2]
a1[[1,3],[0,2]] 错误

a1[[0,1],:] [:,[0,1]]
a1[1:3,[0,2]]

###10  布尔索引
a=np.array(["a","b","a","a"])
a

b[a=='a']

c=np.random.rand(3,4)
c
c[c[:,0]<0.5]

dd=c[  (c[:,0]<0.8) ]
dd

ins=np.array([["张三","女",180],["李四","男",170],["李红","女",160]],dtype=object)
ins
ins[(ins[:,1]=='女') &  (ins[:,2]>170) ]

###11  二维数组的合并
b1=np.array([[1,2,3],[4,5,6]])
np.concatenate((b1,b1),axis=0)
np.concatenate((b1,b1),axis=1)#一维数组的合并不用设定横纵合并

###12  运算
a0=np.array([[1,1,1],
             [2,2,2]])
b0=np.array([[3,3,3],
             [4,4,4]])
a0*b0 #元素对元素的积也称为哈达马积(Hadamard product)
#注意这里要和矩阵的乘法相区别。

a01+a02 # 广播运算 高维的后缘维度 == 低维维度的概念

#某个维度的轴长为1
a=np.array([[0,0,0],
            [1,1,1],
            [2,2,2],
            [3,3,3]])
b=np.array([[1],
            [2],
            [3],
            [4]])
a+b

###13  通用函数
np.add、np.maximun、np.minimun等

###14  ndarray实例的常用方法
#转置
np.array([1,2,3]).T #一维数组转置之后还是自身

a=np.array([[1,2,3]]).T #a的shape是(1,3)
a

a.T #转置之后变成了(3,1)

a=np.arange(12).reshape(3,4) #shape为(3,4)
a
a.T #shape为(4,3)

#transepose方法
a=np.arange(12).reshape(3,4)
a.transpose(1,0)

# astype方法
a=np.arange(12).reshape(3,4)
a.astype(np.float)

a.astype("str")
#a.astype(np.str_)
#a.astype("U")
#上面这几个命令都可以

a=np.array([1,2,3,np.nan])
a.astype("str")

#tolist方法
a=np.array([1,2,3,np.nan])
a.tolist()

###15  np.char模块下面的字符串函数
a=np.array(["a","b","c"])
b=np.array(["1","2","3"])

c=np.array(["1","2",np.nan])
d=np.array(["1","2",None])
np.char.add(b,a)
np.char.upper(a)

a1=np.array(["a b c","d e f"])
a1=np.char.split(a1,sep=" ")
a1.shape

###16  线性代数的矩阵运算
#矩阵的行列式
a=np.random.randint(1,6,(4,4))
np.linalg.det(a) #只有方阵才能求行列式

#矩阵的逆矩阵
a=np.random.randint(1,6,(4,4))
np.linalg.inv(a) #只有方阵才能求逆矩阵

###17  特殊元素构成的数组
=np.array([{1,2},{3,4},{5,6}],dtype="object")
#注意这里dtype="object"可以省略。
#a是一个一维数组,它的shape是(3,)
a=np.array([{1,2},{3,4},{5,6}])
a 
a.ndim

#17.1  二维数组的协方差矩阵
import numpy as np
data1=np.random.rand(2,4)
data1

np.cov(data1) #每一行是一个变量,如果你的变量是列,就要记得转置。
data2=np.array([[1,2,3],
               [3,4,5]])
sum(data2,2)
np.sum(data2,1)

a = np.array([[1, 2, 3], [4, 5, 6]])
a.size

Pandas

  Pandas是Numpy的改进升级版,它解决了numpy的问题,提供了更高级数据框对象等数据结构及方法。

###1. 导入相关的库
import pandas as pd
import numpy as np

###2.Series对象
d=pd.Series(np.random.rand(5),index=list("abcde"))
c[0::2]
d["a":"c"]
d[(d>0.2) & (d<0.5)]

a=pd.Series(["1","2","a"])
pd.to_numeric(a,errors="coerce")

def f1(x):
    try:
        v=float(x)
    except:
        v=np.nan
    return v
a.map(f1)

a.map(lambda x:x+2)

###3.数据框对象
data3=pd.DataFrame([[1,2,3],[4,5,6]],columns=list("abc"))
data2=pd.DataFrame({"a":np.random.rand(10),"b":np.random.rand(10)})
data1=pd.DataFrame(np.random.rand(5,3),columns=["a","b","c"])
pd.read_csv("individual1.csv",encoding="GBK")

a=pd.read_excel("chapter3_1.xls",sheet_name="Sheet1",nrows=10,skiprows=1,header=0)
a.info()
a.head(3)
a.tail()
a.shape
a.columns
a.index
a.T

data1=pd.DataFrame(np.arange(12).reshape(3,4),
                   columns=["a",1,"c","e"],index=list("abc"))
data1[0:2]
data1[["a","c"]]
data1.loc[:,"x1":"x2"]
data1.loc[["a","b"],["x1","x2"]]
data1.iloc[0:2,:]
data1.ix[0:2,"x1":"x2"]
data1[(data1["x1"]>0.5) | (data1["x2"]<0.5)]

data1.pop("x1")
data1.drop(columns=["x2",'x1'],axis=2)#,inplace=False) index=''

data1["z1"]=10
data1["x2"].rank(method="first",ascending=False)
data1["z2"]=data1["x2"]**2
data1["z3"]=data1["x2"].map(lambda x:x**2)
data1.apply(lambda x:max(x.x2,x.x3),axis=1)

a=pd.DataFrame(
	np.random.randint(60,100,(6,3)),columns=["语文","数学","英语"])
a.apply(np.sum,axis=1)

data1.applymap(lambda x:x+2)
data1.rename(columns={"x1":"z1","x2":"z2"})

data1.to_csv("test.csv",index=False)

###3.1 表的合并
pd.concat([data1,data2],axis=0,ignore_index=True)
data1.append(data2,ignore_index=True)

pd.concat([data1,data2],axis=1)#,ignore_index=True)
data1=pd.merge(data1,data2,
               left_on="pid",right_on="pid",
               how="outer",suffixes=("_1","_2"))

###3.2字符串数据还原,缺失值填充,删除无用列,整合数据表
# x.zfill()  +  map 方法 填充还原‘pid’数据
# 不 赋值给原数列 ,那么 不改变原实例
individual1["pid"]=individual1["pid"].astype(str).map(lambda x:x.zfill(7))
individual1.head()

# 自定义一个函数 用于还原填充原数据
def f1(x):
    return "0"*(7-len(str(x)))+str(x)
individual2["pid"]=individual2["pid"].map(f1)
# pd.merge 横向合并,指定表连接的字段,指定连接类型,指定重复列的标签
data1=pd.merge(individual1,individual2,left_on="pid",
         right_on="pid",how="outer",suffixes=("_1","_2"))
data1.head()

# 当fid_1 缺失值时,用fid_2 填充,,,inplace=True表示在原数据上修改
data1["fid_1"].fillna(data1["fid_2"],inplace=True)

# 删除 无用的 列
data1.drop(columns=["fid_2"],errors="ignore",axis=1,inplace=True)

#更改 修改更新后的列的列名
data1.rename(columns={"fid_2":"fid","fid_1":"fid"},inplace=True)
# 年龄_2 有缺失,用年龄_1 的值来换
data1["年龄"]=data1["年龄_2"].fillna(data1["年龄_1"])
# 删除 无用的那两列
data1.drop(columns=["年龄_1","年龄_2"],inplace=True)
#导出数据文件
data2.to_excel("整理好后的数据.xlsx",index=False)

###4.数据框排序
data1=pd.DataFrame(np.random.rand(4,3),
                   columns=["x1","x2","x3"],index=np.arange(4)[::-1])

data1.sort_values(by="x1",ascending=True)
data1.sort_values(by=["x1","x2"],ascending=[True,False],inplace=True)
data1.sort_index(ascending=True,inplace=True)

###5. 变量的描述
data1.describe()# 无参数默认描述数值数据 应该处理好 数据的真实数据类型  eg此处的pid
data1.describe(include=["object"])# 指定描述的数据类型
data1.describe(exclude=["object"],percentiles=[0.1,0.2])
#指定不描述的类型, 添加要描述的统计量percentiles=[0.1,0.2]

###6.查看唯一值 可以用于查重
# 查看唯一值
data1["性别"].unique()

# 查看唯一值并且分别计数
a=data1["性别"].value_counts()

###7.groupby 方法 分组
data1.groupby(data1["性别"])
data1.groupby([data1["性别"],data1["地域编码"]])
group.max()
# 单个变量
data1["年龄"].groupby(data1["性别"]).max()
data1["年龄"].groupby(data1["性别"]).quantile(0.2)
# 多个变量 通常不这样用
data1.groupby(data1["性别"]).max()

# .describe() 不同性别 的 年龄 情况
data1["年龄"].groupby(data1["性别"]).describe()
# agg 方法指定要描述的统计量
data1[["年龄","受教育程度"]].groupby(data1["性别"]).agg(["mean","max","min"])

###8.transform 返回的对象 与原数据的索引保持一致  填充缺失值
data1["年龄"].groupby(data1["性别"]).transform(lambda x:x.count())
data1["年龄"].groupby(data1["性别"]).transform(np.mean)

def f1(x):
    return x.count()
data1["年龄"].groupby(data1["性别"]).transform(lambda x:f1(x))
data1["年龄"].groupby(data1["性别"]).transform(f1)

###8.数据透视表
data1.pivot_table(values=["年龄","受教育程度"],
                  index=["性别","地域编码"],
                 aggfunc={"年龄":[np.mean,np.max],"受教育程度":[np.median]})

###9.变量与索引的相互转化
temp=data1.set_index(["fid","pid"],drop=True)
# 还原变量索引转换,若无变量索引,则将真实索引转换为变量
temp.reset_index()
temp.reset_index().reset_index()

###10.将数值变量进行离散化处理
pd.cut(data1["年龄"],3)
pd.cut(data1["年龄"],[0,45,59,74,89,120],
       labels=["青年","中年","老年前期","老年","长寿老人"])
pd.cut(data1["年龄"],[0,45,59,74,89,120],
       labels=[1,2,3,4,5])

# pd.qcut:用分位数进行分箱
pd.qcut(data1["年龄"],4,labels=[1,2,3,4])

#分箱并计数
pd.qcut(data1["年龄"],4,labels=["青年","中年","老年前期","老年"]).value_counts()

###11.将分类变量转化为虚拟变量(pd.get_dummies)
pd.get_dummies(data1["性别"],prefix="性别")
## 将转换的虚拟变量 合并到  实例数据 ::::  用于分析应选择一列做参考,并将其从数据中删除
pd.concat([data1,  pd.get_dummies(data1["性别"]  ,prefix="性别")],axis=1)
##  drop_first=True 默认以第一个虚拟变量为参考,删除第一个虚拟变量
pd.concat([data1,
           pd.get_dummies(data1["性别"],prefix="性别",drop_first=True)],
          axis=1)

###12.数据框对象的复制
data2=data1.copy(deep=True)

###13.字符串变量的常用方法
data1.fid.str.len()
data1.fid.str.replace("f","a")
data1.fid.str.count("0")
data1.pid.astype(str).str.zfill(5)
series1=pd.Series(["河北省衡水市","河北省石家庄市","河南省郑州市"])
series1.str.extract(r"(.+省)")

###14.判断唯一值
data1=pd.DataFrame([["张三","201",80,90,90],
    ["李四","202",80,90,90],
    ["张三","201",80,90,90]],
    columns=["姓名","学号","语文","数学","英语"])

data1.duplicated()# 判断是否是重复项  返回布尔值
data1.duplicated(subset=["数学","英语"])# 判断 指定数列是否是重复项  返回布尔值

#  保留第一个重复值,删除其他重复数据行记录
data1.drop_duplicates(subset=["数学","英语"],keep="first")

###15.数据框抽样
len(data1.sample(frac=0.3)) #设定了抽取样本比例为10%,所以抽去了100行。
#data1.sample(frac=0.3)
#data1.sample(frac=0.1)
#replace=False表示无放回抽样。
#random_state是设定随机种子,保证每次运行代码抽取到的样本一样。

###16.时间变量的处理
#pd.Timestamp 返回时间戳 对象
pd.Timestamp("2017-01-02T12")#传入字符串
pd.Timestamp("2017/1/1")
pd.Timestamp(1, unit='s', tz='Asia/Shanghai')
#根据距离纪元的秒数生成时间戳(可设定时区)
#根据距离纪元的秒数生成指定时区的时间,默认是0时区。
pd.Timestamp(2017,1,1,1)
pd.datetime(2017,1,1)
pd.Timestamp(pd.datetime(2001,1,1))
#pd.to_datetime  返回时间戳 对象
pd.to_datetime("2019/08/31",format="%Y/%m/%d",errors="coerce")

pd.to_datetime(1,unit="s")
pd.to_datetime(pd.datetime(2019,8,28))

pd.datetime.now()# 不是正常的时间 格式
import datetime
datetime.datetime.now()# 不是正常的时间 格式
import time
time.localtime()# 不是正常的时间 格式
datetime.datetime.now().timetuple()# 不是正常的时间 格式

###时间戳实例的属性和方法
a=pd.Timestamp("2017-1-1T12:9:6")
a.year
a.month
a.day
a.hour
a.minute
a.second
a.dayofweek+1
a.time()
a.date()
a.value
a.timestamp()
a.strftime("%Y-%m-%d")
a.strftime("%A")

###计算时差Timedelta实例
a=pd.Timestamp("2019/8/28T15:49:30")
b=pd.Timestamp("2019/8/27T15:30:20")
a-b

cd=pd.Timedelta(days=1,hours=2,minutes=3,
                seconds=4,milliseconds=5,microseconds=6,nanoseconds=7)
cd.total_seconds()
cd.delta
cd.components
cd.components.days
cd.components.milliseconds

### 生成时间戳范围
a=pd.date_range("2001-1-1",freq="D",periods=10)# 元素为时间字符串的 时间戳列表
###时间数据 处理 实例
data1=pd.read_excel("上证指数日收盘价数据.xls")
data1.head()
data1.info()
data1.drop(columns=["index"],inplace=True)


data1["year"]=data1["date"].dt.year
data1["month"]=data1["date"].dt.month
data1["day"]=data1["date"].dt.day
data1["dayofweek"]=data1["date"].dt.dayofweek+1

#如何把年月日时间变成年月时间
data1["ym"]=data1["date"].dt.to_period(freq="M")
data1["date1"]=data1.apply(lambda x:pd.Timestamp(x["year"],
                                                 x["month"],x["day"]),axis=1)
pd.to_datetime(data1["datestr"],format="%Y/%m/%d",errors="coerce")
data1["date2"]=pd.to_datetime(data1["num"],unit="s")
data1["date3"]=data1["num"].map(lambda x:pd.Timestamp(x,unit="s",tz="Asia/Shanghai"))

data1["date"]+pd.Timedelta(days=30)

###求变量的滞后一期
data1["p"].shift(1)

###求变量的先导一期
data1["p"].shift(-1)

import math
data2["r"]=data2["p"].map(lambda x :math.log(x))-data2["p1"].map(lambda x:math.log(x))

###日期时间变量用做数据框的索引
data2.index=data2["date"]
data2["p"]["2003-1-8"]
data2["p"]["2003-1"]
data2["p"]["2003-1-1":"2003-1-10"]
data2[(data2.index>"2003-10-1") & (data2["r"]>0)]
data2.to_period(freq="M")

series1=pd.date_range("2003-1-1",freq="D",periods=100)

data1=pd.DataFrame(np.random.rand(100,2),columns=["x1","x2"])
data1.index=series1

data2=data1.asfreq(freq="5D")
data2.asfreq(freq="D").head(10)

data2.asfreq(freq="D",method="pad")

  上面的两块代码区便是numpy、pandas库在数据清洗中常用的形态了,后期若研究出新的使用方式,会专门补充。

发布了39 篇原创文章 · 获赞 42 · 访问量 4872

猜你喜欢

转载自blog.csdn.net/weixin_41774099/article/details/100376133
今日推荐