Pandas的优势:除了处理数值数据之外(基于NumPy),还能够处理其他类型的数据(字符串,时间序列等)
1.常见数据类型
Series一维,带标签数组(键:索引,index -- 值:values)
DataFrame二维,Series容器
2.创建与读取
2.1创建
Series:
import pandas as pd
import string
s1 = pd.Series([90,20,43,100,23],index=(list(string.ascii_uppercase[:5]))) # 创建一个数组,并设置其索引
print(s1)
DataFrame:
import pandas as pd
import string
df = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list(string.ascii_uppercase[:4]))
print(df1)
2.2数据的读取
pd.read_csv("路径/文件名", header = 0) # header设置数据的第几列为行索引
pd.read_sql() #
2.3数据的保存
pd.save_csv("保存文件名.csv",index_label=False) # index_label设置是否保存索引
d.save_csv()
3.基础属性
import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list(string.ascii_uppercase[:4]))
df.shape # 行数,列数
df.dtypes # 列数据类型
df.ndim # 数据维度
df.index # 行索引
df.columns # 列索引
df.head(3) # 显示头部几行,默认5行
df.tail(2) # 显示末尾几行,默认5行
df.info() # 相关信息概览:行数,列数,列索引,列非空值个数,列类型,内存占用
df.describe() # 快速综合统计结果:记数,均值,标准差,最大值,四分位数,最小值df.sort_values(by="排序关键字",ascending=Turn升/False降)
4.数据切片
查看索引:df.index
查看值:df.values
切片:格式[起始:结束:步长(可选)]
索引:单个时直接传入序号或index,多个时传入序号或index的列表
import numpy as np
import pandas as pd
import string
df = pd.DataFrame(np.arange(40).reshape(10,4),index=list("abcdefghij"),columns=list(string.ascii_uppercase[:4]))
# 只有1个[]时 获取行
# 当[[]] 2个中括号嵌套时,获取列
df[0:5:2] # 切片:格式[起始:结束:步长(可选)](获取行可用)
df["a":"b"] # 获取指定范围内的列
df[["A","B","D"]] # 获取指定列
取符合条件的内容:
# Series写法:
df[df>10]
# DataFrame写法:
df[df["列名"] 条件语句]
df[df["A"]>10]
df.loc[]:(处理非数值)通过标签索引行数据
#对于数据的选择分为 3 种(获取行同理)
df.loc[:,"A"] # 获取指定列
df.loc[:,"A":"D"] # 获取包括A列到D列的中间所有列的数据
df.loc[:,["A","D"]] # 只获取A和D列(注意多了"[]",多个索引间用 "," 隔开)
df.loc[df["A"]>0,"A"] # 对指定列判断,满足条件则返回
df.loc[行索引名称 / df["列名"] 条件语句,"列名" # (处理非数值)通过标签索引行数据
# 条件筛选的示例
df.loc[df["A"]>0,:] # 返回数据集中,A列值大于0的行
df.iloc[]:(处理数值)通过位置获取行数据
# 用法上与loc相同,但其只能使用数字,且不能使用条件语句
df.iloc[行索引,列索引]
df.iloc[:,3] # 返回指定列
df.iloc[6,0:4] # 返回指定行的所有数据
df.iloc[0:6,0:3] # 返回范围内的行,列的数据
5.布尔索引
& :且
| :或
用法:
df[(df条件语句1) & (条件语句2) | (条件语句3)]
# 注意点:不同条件之间需要用括号括起来
import numpy as np
import pandas as pd
import string
df = pd.DataFrame(np.arange(40).reshape(10,4),index=list("abcdefghij"),columns=list(string.ascii_uppercase[:4]))
df = df[(df["A"]>0)&(df["D"]<24)|(df["B"]>10)&(df["B"]<23)]
df
# 使用次数超过700,并且名字的字符串的长度大于4
# df = df[(df["Row_Labels"].str.len()>4)&(df["Count_AnimalName"]>700)]
6.字符串方法
7.缺失数据的处理
缺失数据的判断,以及提取
# 判断数据
df[df["列名"].isnull().values==True] # 找出该列数据为NaN的行
df["列名"].isnull().any() # 判断该列是否 有 NaN
df["列名"].isnull().all() # 判断该列是否 全部为NaN
pd.isnull(df)
pd.notnull(df)
# 提取出不为空的数据
df = df[pd.notnull(df)]
df = df[pd.notnull(df["列名"])]
第1种:直接删(不推荐)
df.dropna (axis=0, how='any', inplace=False) # 删除NaN所在的行/列
how
:指定删除方式
axis
:指定按行删还是按列删
inplace
:是否对原数据进行修改,默认False
第2种:填充数据
注意:计算平均值等情况,nan是不参与计算的,但是0会
# 对指定行,使用均值填充
df.fillna(df["C"].mean())
# 用中值来填
df.fiallna(df.median())
# 用指定值填充
df.fillna(0)
第3种:使用算法填充
pass
8.常用统计方法
数据去重:
Series:1维用
df.unique()
DataFrame:多维用
df.drop_duplicates(["列1","列2"]) # 设置需要去重的列
平均数:df["列索引"].mean().round(2) # (round)保留小数点后2位
查看列中有多少个不同的值,并求各自总和:df[''索引列"].value_counts()
替换空值为指定内容:
去重:list(set(数据集))
将数组/矩阵转为列表:df.tolist()
将数据转为字典:df.to_dict()
9.分组和聚合:
合并数据集:
测试生成数据:
import pandas as pd
import numpy as np
import string
df1 = pd.DataFrame(np.ones((3,4)),index=list("ABC"),columns=list("NOPQ"))
df2 = pd.DataFrame(np.zeros((2,5)),index=list("AB"),columns=list(string.ascii_uppercase[:5]))
第1种方法:join()
# 默认是把行索引相同的数据合并到一起
df1.join(df2)
第2种方法:merge() 将相同指定列相同的数据合并(类似数据库的:等值连接)
# 将df1和df2中指定字段相同的数据合并
t3 = pd.merge(left=df1,right=df2,left_on="df1字段名",right_on="df1字段名")
df1['O'] = list("abc")
print(df1)
df2["C"] = list("cd")
print(df2)
# 将df1的"O"字段和df2的"C"字段相同的数据合并
df3 = pd.merge(left=df1,right=df2,left_on="O",right_on="C",how="")
print(df3)
how = " "
:关键字,设置是否需要而外的连接
inner
:并集(默认)
outer
:交集,NaN补全
left
:左表为准,NaN补全(左外连接)
right
:右表为准,NaN补全(右外连接)
第3种方法:concat() 默认纵向合并,列数与列名要对应相同
axis = 0/1
# 横 / 竖排序
join = 'outer'
# 设置方法(交并集等)
ignore_index = False
# 是否重新创建index
9.分组和聚合:df.groupby(by=[""]).count()
DataFrame.groupby(by=["columns"]).count() # 以指定字段进行分组计数
10.索引和复合索引:df.index
简单的索引操作:
#索引:index
import pandas as pd
df = pd.DataFrame({'a':range(7),
'b':range(7,0,-1),
'c':['one','one','one','two','two','two','four'],
'd':list("HIJKMMM")})
# 获取索引
print(df.index)
# 指定/改变索引
df.index = ['索引名1','22','33','44','55','66','66'] # 必须和原索引长度相同
# 指定某一列作为索引/index
df = df.set_index(["b","d"],drop=False) # drop是否保存被作为索引的那一列,默认删除(可设置多个索引名,用 [ ] 加 , )
print(df)
# 返回指定index的唯一值
df = df.set_index("列名").index.unique()
print(df)
复合索引:df.set_index()
备注:Series的复合索引直接写在括号中即可(DataFrame多个 中括号[])
# 复合索引
df = pd.DataFrame({'英伟达':range(7),
'AMD':range(7,0,-1),
'国家':['中国','中国','中国','中国','美国','美国','巴西'],
'省份':['北京','上海','广州','深圳','加州','新泽西','里约']})
print(df)
# 设置复合索引
df = df.set_index(['国家','省份'])
print(df)
# 访问复合索引中指定列的值
df = df.loc["中国",:].loc["北京","AMD"]
print(df)
附加部分:修改columns/行标签
# 直接改:(修改的个数需要相等)
df.columns = ["A","B","C","D"]
# 暴力:(好处可只修改特定的列)
df.rename(columns=('$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}, inplace=True)
# 修改:
df.rename(columns=lambda x:x.replace('$',''), inplace=True)
内容参考:Pandas:DataFrame数据的更改、插入新增的列和行
插入新增列、行
在最后位置新增列
# 在数据框尾部增加一列,注意其元素个数要跟原数据列的个数一样
df["add_list"]=["a","b","c","d"]
在指定位置新增列:insert()
# 语法格式:列表.insert(index, obj)
# index --->对象 obj 需要插入的索引位置。
# obj ---> 要插入列表中的对象(列名)
col_name=df.columns.tolist() # 将数据框的列名全部提取出来存放在列表里
print(col_name)
col_name.insert(2,'city') # 在列索引为2的位置插入一列,列名为:city,刚插入时不会有值,整列都是NaN
df=df.reindex(columns=col_name) # DataFrame.reindex() 对原行/列索引重新构建索引值
df['city']=['北京','山西','湖北','澳门'] # 给city列赋值
print(df)
在原数据框末尾新增一行:df.append()
# 注意:需先创建一个DataFrame,用来增加进数据框的最后一行
new_data=pd.DataFrame({'name':'lisa'
,'gender':'F'
,'city':'北京'
,'age':19
,'score':100}
, index=[1]) # 自定义索引为:1 ,也可以不设置index
print(new_data)
# ignore_index=True,表示不按原来的索引,从0开始自动递增
df=df.append(new_data,ignore_index=True)
print(df)
11.时间序列:pd.date_range()
pd.date_range(start=None, end=None, periods=None, freq='D')
#1.start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引
#2.start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索引
#将字符串转时间类型
df["timeStamp"] = pd.to_datetime(df["timeStamp"],format="") # 其中format参数大部分情况下可以不用写
#DataFrame中使用时间序列
index=pd.date_range("20170101",periods=10) #生成时间序列
df = pd.DataFrame(np.random.rand(10),index=index) #将时间序列指定为index
freq的参数:
12.重采样:df.resample()
重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样
注意点
:重采样时索引必须为时间类格式
# 将时间序列设置成行索引
df = pd.DataFrame(np.random.randint(1,100,(100,1)),index = pd.date_range(start="20200501",periods=100))
print(type(df))
print(df)
# 重采样(索引必须为时间类格式)
ret = df.resample("M").sum()
print(ret)
13.重组时间序列pd.PeriodIndex()
主要将数据中的分离的时间字段,重组为时间序列,并指定为index
#把分开的时间字符串通过periodIndex的方法转化为pandas的时间类型
period = pd.PeriodIndex(year=df["year"],month=df["month"],day=df["day"],hour=df["hour"],freq="H")
print(period)
df["datetime"] = period
#把datetime 设置为索引
df.set_index("datetime",inplace=True)