Pandas主要处理三个数据结构
- Series (序列) 处理一维数据
- DataFrame (数据帧) 处理二维数据
- Panel (面板) 处理三维数据
显示所有列
pd.set_option(‘display.max_columns’, None)
len(df)表示行数
转化类型的时候要记得把变量重新给该字段
today_world['病死率'] = today_world['病死率'].astype('float')
获取series的值.values[0]
Series的创建
语法: pandas.Series( data, index, dtype, name, copy, fastpath)
Serie默认的index从0开始, 也可以自己指定
默认创建
s1 = pd.Series(
[1, 2, 3, 4, 5, 6, 7],
index=["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
)
print(s1)
用ndarray创建Series
n1 = np.arange(1,11)
s2 = pd.Series(n1)
print(s2)
用字典创建Series
d = {4: 'four', 5: 'five', 6: 'five', 7: 'seven'}
s4 = pd.Series(dz,index=[5,4,7,6,1])
# 若索引自定义的顺序不同, 则会变换,没有的索引值为nan
print(s4)
Series的索引,切片
d = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7}
s4 = pd.Series(d)
# 按默认的索引顺序来查找
print(s4[3])
print(s4[:3])
# 按索引的值来查找
print(s4['one'])
print(s4[['one','two','six']])
得到Series的索引和值的列表
print(s4.index.tolist())
print(s4.values.tolist())
Series的排序统计
rate = pd.Series(
data=[3,4,5,3,5,2,1,3,5,4,3,3,5],
name='评分',
)
print(rate.value_counts()) # 统计系列中每个值出现的次数,以 值 次数 的形式返回,降序排列
print(rate.value_counts()[值]) # 得到某个值出现的个数
print(rate.sort_values()) # 按Series的值进行升序排列
d = {4: 'four', 5: 'five', 1: 'one', 7: 'seven'}
# 按索引进行排序, 降序
print(pd.Series(d).sort_index(ascending=False))
DataFrame的创建
语法: pandas.DataFrame( data, index, columns, dtype, copy)
data: 可以是列表, 字典等, 若用字典创建,则value要使用列表形式
list1 = [['张三', 23, '男'], ['李四', 27, '女'], ['王二', 26, '女']]
df1 = pd.DataFrame(list1, columns=['姓名', '年龄', '性别'])
df2 = pd.DataFrame({'姓名': ['张三', '李四', '王二'],
'年龄': [23, 27, 26],
'性别': ['男', '女', '女']
})
arr3 = np.array(list1)
df3 = pd.DataFrame(arr3,columns=['姓名','年龄','性别'])
print(df1)
print(df2)
print(df3)
查看dataframe的属性(获取表头)
用法 | 解释 |
---|---|
df.info() | 查看df的信息 |
df.head/tail(number) | 查看df的前/后几列 |
df.index | df的索引(行标签) |
df.values | 返回DataFrame的Numpy表示形式 |
df.columns | df的列标签。 |
df.ndim | 返回一个表示轴数/数组维数的整数。 |
df.size | 返回一个表示此对象中元素数量的int。 |
df.shape | 返回一个表示df维数的元组。 |
df = df.astype({‘列名’:‘数据类型’}) | 把df中的某几列的数据类型强制转换 |
df.describe(incloude) | 描述数据的有些相关性信息, 参数=”all”表示非数值类型也进行描述 |
df的索引(数据查找,筛选)
用法 | 解释 |
---|---|
df[‘列名’] | 索引处所要的列的书v就 |
df.loc[行索引名/条件, 列名] | 通过标签或布尔数组访问一组行和列。 |
df.iloc[] | 通过索引数字来访问 [前几行或[1,2]第二行第三行 ,需要的列数或[1,3]第二列,第四列] |
df[].isin() | 判断某列的值是否存在于[] |
df.set_index(‘列名’) | 将某一列设置为索引 |
list1 = [['张三', 23, '男'], ['李四', 27, '女'], ['王二', 26, '女']]
arr3 = np.array(list1)
df3 = pd.DataFrame(arr3,columns=['姓名','年龄','性别'],index=[['第一个','第二个','第三个']])
print(df3)
'''
姓名 年龄 性别
第一个 张三 23 男
第二个 李四 27 女
第三个 王二 26 女
'''
df3.loc[df3['性别'] == '男','性别'] = 1
df3.loc[df3['性别'] == '女','性别'] = 0
print(df3)
'''
姓名 年龄 性别
第一个 张三 23 1
第二个 李四 27 0
第三个 王二 26 0
'''
print(df3.loc[['第一个','第三个'],'姓名'])
'''
第一个 张三
第三个 王二
'''
print('-'*11)
print(df3.iloc[[0,2],[0,-1]])
'''
姓名 性别
第一个 张三 男
第三个 王二 女
'''
print(df3.iloc[0:3,2])
'''
第一个 男
第二个 女
第三个 女
'''
df3['性别'] = np.where(df3['性别']=='男','1','0')
print(df3)
df3.loc[df3['性别']=='男','性别']='1'
df3.loc[df3['性别']=='女','性别']='0'
print(df3)
'''
姓名 年龄 性别
第一个 张三 23 1
第二个 李四 27 0
第三个 王二 26 0
姓名 年龄 性别
第一个 张三 23 1
第二个 李四 27 0
第三个 王二 26 0
'''
df的运算统计
求表中某几列的和
print(df.iloc[:,1:8].sum(axis=1))
# 表中所有行, 1到7列的和, axis表示求列之和, 默认为求每行该列的值的和
df3['年龄'] = df3['年龄'].astype(int)
df3['年龄'] = df3['年龄']*2
print(df3)
对数据进行增删改
语法 | 描述 |
---|---|
df.drop(labels=[行/列索引名称], axis, inplace) | 删除某行/列 |
df.insert(loc, column, value) | 选择列的索引位, 列名, 数据插入 |
df.drop(df[df["用户年龄"]<q1-1.5*iqr].index,inplace=True)
df.drop(df[df["用户年龄"]<q2+3*iqr].index,inplace=True)
# 增加列
df3['是否成年'] = np.where(df3['年龄']>'18','是','否')
df3['国籍'] = ['中国','中国','中国']
print(df3)
'''
姓名 年龄 性别 是否成年 国籍
第一个 张三 23 1 是 中国
第二个 李四 27 0 是 中国
第三个 王二 17 0 否 中国
'''
# 删除列
df3.drop(labels=['是否成年','国籍'],axis=1,inplace=True)
print(df3)
# 删除行
df3.drop(labels=['第一个','第三个'],axis=0,inplace=True)
print(df3)
# 插入
df3.insert(0,'国籍',['中国','中国','中国'])
print(df3)
对于缺失值的处理
删除
对于缺失值可以计算一下该字段缺失值的占比
volum = df.apply(lambda x: sum(x.isnull())/len(x), axis=0)
若缺失值过多可以剔除这一列
语法: df.dropna(how, subset=[], inplace) 默认为any只要有缺失值就删除
how:all->全为缺失值才删除
subset: 指定哪些列为空,才删除该行
df = pd.DataFrame({'姓名': ['张三', '李四', '王二','赵六','赵四','王五'],
'年龄': [23, 27, 26,23,None,None],
'性别': ['男', '女', '女',None,np.nan,'男']
})
print(df)
'''
姓名 年龄 性别
0 张三 23.0 男
1 李四 27.0 女
2 王二 26.0 女
3 赵六 23.0 None
4 赵四 NaN NaN
5 王五 NaN 男
'''
df.dropna(how='any',subset=['姓名','性别'],inplace=True)
print(df)
'''
姓名 年龄 性别
0 张三 23.0 男
1 李四 27.0 女
2 王二 26.0 女
5 王五 NaN 男
'''
填补
对于缺失值可以用0填补,若为int型可以用其一整列的均值,众数来填充
若为str类型可以用其出现最多的值来填充
语法: df.fillna(value, method, inplace)
value: 指定填充的值, 可用字典形式每列所要填充的类型
method: ffill/bfill 向前/后填充
mode = df['性别'].mode()[0]
df.fillna(value={'年龄':df['年龄'].mean(),'性别':df['性别'].mode()[0]},inplace=True)
print(df)
'''
姓名 年龄 性别
0 张三 23.00 男
1 李四 27.00 女
2 王二 26.00 女
3 赵六 23.00 女
4 赵四 24.75 女
5 王五 24.75 男
'''
对于重复值的处理
首先要查看是否存在重复值
print(any(df.duplicated()))
# 显示重复的行
print(df[df.duplicated()])
语法: df.drop_duplicates(subset, keep, inplace, ignore_index)
subset: 指定哪些字段重复才删除(类似于sql的unique)
keep: first: 从第二个开始, 和第一个相同的就为重复值, 返回True
last: 从倒数第二个开始, 和倒数第一个相同的就为重复值, 返回True
ignore_index: 删除重复之后, 重置索引
删除重复数据(所有字段的相同的才删除)
df.drop_duplicates(subset=['姓名','性别'],inplace=True,ignore_index=True)
print(df)
'''
姓名 年龄 性别
0 张三 23.0 男
1 李四 27.0 女
2 王二 26.0 女
3 赵六 23.0 None
4 赵四 NaN NaN
5 王五 NaN 男
6 王二 26.0 男
'''
分组聚合
分组
语法: df.groupby(by=[])
by: 可以是多个列名
使用groupby对象,可以遍历类似itertools.obj的对象。
ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
'Year':[2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}
df = pd.DataFrame(ipl_data)
print(df)
# print(df.set_index(['Year','Team']))
grouped = df.groupby('Year')
print(grouped)
for name,group in grouped:
print (name)
print (group)
'''
2014
Team Rank Year Points
0 Riders 1 2014 876
2 Devils 2 2014 863
4 Kings 3 2014 741
9 Royals 4 2014 701
2015
Team Rank Year Points
1 Riders 2 2015 789
3 Devils 3 2015 673
5 kings 4 2015 812
10 Royals 1 2015 804
2016
Team Rank Year Points
6 Kings 1 2016 756
8 Riders 2 2016 694
2017
Team Rank Year Points
7 Kings 1 2017 788
11 Riders 2 2017 690
'''
聚合
对分组后的对象使用聚合函数(可以有多个聚合函数)
# 对队伍做分组, 依据队伍分数的总和,平均值做聚合
x = df.groupby(['Team']).agg([np.sum, np.mean])['Points']
# 若不指定对哪一列做聚合则默认对全部列
print(x)
'''
sum mean
Team
Devils 1536 768.000000
Kings 2285 761.666667
Riders 3049 762.250000
Royals 1505 752.500000
kings 812 812.000000
'''
# 也可以用字典的形式
x = df.groupby(['Team']).agg({'Points':[np.sum,np.mean],'Rank':[np.sum,np.mean]})
print(x)
'''
Points Rank
sum mean sum mean
Team
Devils 1536 768.000000 5 2.500000
Kings 2285 761.666667 5 1.666667
Riders 3049 762.250000 7 1.750000
Royals 1505 752.500000 5 2.500000
kings 812 812.000000 4 4.000000
'''
透视表
语法: df.pivot_table(data, value, index, columns aggfunc, fill_value,
margins, margins_name)
value: 要汇总的列(可选)
index: 行分组键
column: 列分组键
aggfunc: 使用的聚合函数(可用字典)
fill_value: 用于替换缺失值
margins: 是否需要总计
margins_name: 总计的名称
pivot = pd.pivot_table(
data=df,
values=["Points","Rank"],
index="Team",
aggfunc=[np.mean]
)
print(pivot)
数据的,连接
pd.concat([data1,data2], join=”, ignor_index=False)
df1= pd.DataFrame(np.ones([3,4],dtype=int),columns=['a','b','c','d'])
df2 = pd.DataFrame(np.zeros([3,4], dtype=int), columns=['b','c','d','e'])
print(df1)
print(df2)
a b c d
0 1 1 1 1
1 1 1 1 1
2 1 1 1 1
b c d e
0 0 0 0 0
1 0 0 0 0
2 0 0 0 0
con = pd.concat([df1,df2],join='inner',ignore_index=True) # 留下相同的, 把不同的列去掉
print(con)
b c d
0 1 1 1
1 1 1 1
2 1 1 1
3 0 0 0
4 0 0 0
5 0 0 0
语法:pd.merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None)
left: 左边的数据集
right: 右边的数据集
how: 连接方式: inner outer left right
on: 选择连接的键
left_on: 左边连接的键
right_on: 右边连接的键
data1 = pd.DataFrame({
'key':['a','b','a','c','b','d'],
'data1':[1,2,3,4,5,6]
})
data2 = pd.DataFrame({
'rkey':['a','b','c'],
'data2':[8,9,7]
})
data3 = pd.DataFrame({
'key':['a','b','a','c','b','d'],
'data1':[1,2,3,4,5,6]
})
data4 = pd.DataFrame({
'key':['a','b','c'],
'data2':[8,9,7]
})
print(pd.merge(data3,data4,how='left',on='key'))
merge = pd.merge(data1,data2,left_on='key',right_on='rkey',how='left')
# 若两个表要合并的列名不同,需要指定left_on和right_on,how,再把不需要的列删除即可
merge.drop('rkey',axis=1,inplace=True)
print(merge)
'''
key data1 data2
0 a 1 8.0
1 b 2 9.0
2 a 3 8.0
3 c 4 7.0
4 b 5 9.0
5 d 6 NaN
key data1 data2
0 a 1 8.0
1 b 2 9.0
2 a 3 8.0
3 c 4 7.0
4 b 5 9.0
5 d 6 NaN
'''
数据的转换
日期格式的转换
用to_datetime()方法将文本格式转换为日期格式
dataframe数据类型如果为datetime4, 可以使用dt方法取出年月日等
对于时间差数据,可以使用timedelta函数将其转换为指定的时间单位的数值
时间差数据可以使用dt方法访问其常用属性
# 把数据变成时间格式再提取年份数据
# 方法1
ffp = data['FFP_DATE'].apply(lambda x:datetime.strptime(x, '%Y/%m/%d'))
ffp_year = ffp.map(lambda x: x.year)
print(ffp_year)
# 方法2
data["FFP_DATE"] = pd.to_datetime(data['FFP_DATE'],format='%Y/%m/%d',errors='coerce')
print(data["FFP_DATE"].dt.year)
print(df['day'].head(5))
'''
0 20140919
1 20131011
2 20131011
3 20141023
4 20141103
'''
# 把日期转换为相对应的格式errors coerce==格式不对的变为nat
df['buy_day'] = pd.to_datetime(df['day'],format='%Y%m%d',errors='coerce')
print(df['buy_day'].head(5))
'''
0 2014-09-19
1 2013-10-11
2 2013-10-11
3 2014-10-23
4 2014-11-03
'''
利用map,appl转换
df = pd.DataFrame({"id":[1,2,3,4,5,6], "grade":['A', 'B', 'B', 'A', 'C', 'D']})
print(df.info())
print('---')
print(df)
'''
id grade
0 1 A
1 2 B
2 3 B
3 4 A
4 5 C
5 6 D
'''
def translate(x):
if x=='A':
return '优秀'
if x =='B':
return '良好'
if x == 'C':
return '及格'
if x=='D':
return '不及格'
# df['raw_grade'] = df['raw_grade'].apply(translate)
# print(df)
df['grade'] = df['grade'].map({'A':"优秀",'B':'良好','C':'及格','D':'不及格'})
print(df)
'''
id grade
0 1 优秀
1 2 良好
2 3 良好
3 4 优秀
4 5 及格
5 6 不及格
'''
读取,保存,合并文件
CSV
语法: pd.read_csv(filepath_or_buffer, sep=’,’, names=None, index_col=None, dtypy=,encording=‘utf-8’ )
filepath_or_buffer: 文件路径
sep: 分隔符
name: 自定义表头
index_col: 自定义索引列
dtype: 可以用字典的形式指定某些列的数据结构
Excel
语法: pd.read_excel(io, sheet_name)
io: 文件路径
sheet_name: 指定工作簿
合并多个工作簿
import xlrd
wordbook = xlrd.open_workbook('meal_order_detail.xlsx')
sheet_name = wordbook.sheet_names()
# print(sheet_name) # 以列表的形式显示出工作簿的名称
order1 = pd.read_excel('meal_order_detail.xlsx',sheet_name='meal_order_detail1')
order2 = pd.read_excel('meal_order_detail.xlsx',sheet_name='meal_order_detail2')
order3 = pd.read_excel('meal_order_detail.xlsx',sheet_name='meal_order_detail3')
# 工作簿合并, 并且重置索引,纵向堆叠
'''
# 方法一
order = pd.concat([order1,order2,order3],axis=0,ignore_index=True)
print(order.tail(10))
'''
'''
# 方法二
basic = pd.DataFrame()
for i in sheet_name:
basic_i = pd.read_excel('meal_order_detail.xlsx',sheet_name=i)
basic = pd.concat([basic,basic_i],axis=0,ignore_index=True)
print(basic.shape)
'''
SQL
对于sqlite数据库
conn = sqlite3.connect('***.db')
sql = "select * from table_name"
comment_data = pd.read_sql_query(sql, conn)
对于MySQL
from sqlalchemy import create_engine
def query(table):
user = 'root'
password = '***'
ip = 'localhost'
port = 3306
database = '***'
conn = create_engine(r'mysql+pymysql://{}:{}@{}:{}/{}'.format(user,password,ip,port,database))
sql = "select * from {}".format(table)
return pd.read_sql(sql,conn)
文件保存
df.to_excel('***.xlsx',encording='utf-8',index=False)
df.to_csv('*****.csv',encoding='utf-8',index=False)
# 把多个df保存存到同一个excel文件的不同sheet中
writer = pd.ExcelWriter("中国各省的数据.xlsx") # 设置文件路径
df.to_excel(writer,encoding='utf-8',index=False,sheet_name=df_name[i]+"的数据")
writer.save()
# 将多个df放到同一个excel的同一个sheet中
import pandas as pd
df = pd.DataFrame({'姓名': ['张三', '李四', '王二'],
'年龄': [23, 27, 26],
'性别': ['男', '女', '女']
})
df2 = df.copy()
dfs = []
dfs.append(df)
dfs.append(df2)
df = pd.concat(dfs)
df.to_excel('test3.xlsx',index=False)
脱敏处理
import pandas as pd
df = pd.read_excel('sfz.xlsx',dtype=str)
print(df)
df['脱敏处理后'] = df['身份证号码'].apply(lambda x:str(x).replace(x[5:15],'**********'))
print(df)
'''
身份证号码
0 110101199003076992
1 110101199003074000
2 110101199003076992
3 110101199003074000
4 110101199003072000
身份证号码 脱敏处理后
0 110101199003076992 11010**********992
1 110101199003074000 11010**********000
2 110101199003076992 11010**********992
3 110101199003074000 11010**********000
4 110101199003072000 11010**********000
'''
循环读取数据, 保存到一个excel文件中
each_nations_day_list_df = pd.read_excel(r'E:\Python_Project\COVID-19疫情的数据科学实践\各国数据_2020-04-22.xlsx')
# each_nation_writer =pd.ExcelWriter('各国每日数据.xlsx')
data1 = pd.DataFrame()
for i in range(3):
url = 'https://c.m.163.com/ug/api/wuhan/app/data/list-by-area-code?areaCode={}'.format(each_nations_day_list_df['id'].iloc[i])
time.sleep(0.5)
r = requests.get(url,headers=headers)
data_json = json.loads(r.text)
data = get_data(data_json['data']['list'],['date','lastUpdateTime'])
data['name'] = each_nations_day_list_df['name'][i]
data['id'] = each_nations_day_list_df['id'][i]
all_data = pd.concat([data,data1])
data1 = all_data
all_data.to_excel('测hi.xlsx')
循环读取数据, 保存到一个excel文件中
each_nations_day_list_df = pd.read_excel(r'E:\Python_Project\COVID-19疫情的数据科学实践\各国数据_2020-04-22.xlsx')
# each_nation_writer =pd.ExcelWriter('各国每日数据.xlsx')
data1 = pd.DataFrame()
for i in range(3):
url = 'https://c.m.163.com/ug/api/wuhan/app/data/list-by-area-code?areaCode={}'.format(each_nations_day_list_df['id'].iloc[i])
time.sleep(0.5)
r = requests.get(url,headers=headers)
data_json = json.loads(r.text)
data = get_data(data_json['data']['list'],['date','lastUpdateTime'])
data['name'] = each_nations_day_list_df['name'][i]
data['id'] = each_nations_day_list_df['id'][i]
data.to_csv('测试2csv.csv',mode='a',encoding='utf_8_sig')
提取数值类型的数据
df.select_dtypes(include=[np.number])
设置某列为索引,某列为数据pivot
import seaborn as sns
import pandas as pd
df2 = pd.DataFrame({'姓名': ['张三', '李四', '王二'],
'年龄': [23, 27, 26],
'性别': ['男', '女', '女'],
'工资': [100,200,300],
'省份': ['福建','浙江','广东']
})
print(df2)
print('--=--')
print(df2.pivot(index='姓名',columns='省份',values=['工资','性别']))
‘’‘
姓名 年龄 性别 工资 省份
0 张三 23 男 100 福建
1 李四 27 女 200 浙江
2 王二 26 女 300 广东
--=--
工资 性别
省份 广东 浙江 福建 广东 浙江 福建
姓名
张三 NaN NaN 100 NaN NaN 男
李四 NaN 200 NaN NaN 女 NaN
王二 300 NaN NaN 女 NaN NaN
’‘’
pandas dataframe 分组聚合时,分组组名并入列的方法
import pandas as pd
data = pd.read_excel("数据.xlsx")
df = data[["名称","准确率"]]
result = df.groupby(df["名称"],as_index=False).sum() # 这里要使用as_index参数
complete = result.loc[result["准确率"]>=1]
incomplete = result.loc[result["准确率"]<1]
newc=pd.DataFrame(complete)
print(newc)
between的使用
between是针对某一列(series)进行计算的
series[series.between(n1,n2,inclusive=True)].count()
# inclusive代表包括端点
两个df上下合并
result_df = df1.append(df2)
df增加一列
data_list = []
df["新的一列"] = data_list
# 默认加载最后一列
# 如果需要插入到指定位置
df.insert(第几列, '列名', data_list)
# 最后一列:len(df.columns)