Pandas笔记
2022-10-07 本文已影响0人
会爬虫的小蟒蛇
文件读取
import pandas as pd
import pymysql
# 读取纯文本
datas = pd.read_csv(
"csv path",
sep="文本分割符",
engine="python", # 当 sep 与正则表达式冲突时使用,表示 sep 中不是正则表达式
header=None,
names=["姓名", "年龄", "性别"]
)
# 读取Excel
datas = pd.read_excel(r"xlsx path")
# 读取数据库
conn = pymysql.connect(
host="127.0.0.1",
user="账号",
password="密码",
database="数据库名",
charset="utf8"
)
datas = pd.read_sql("select * from user", con=conn)
# 保存 to_xxx
datas.to_excel("xlsx path", index=False)
数据基本查询
dataframe.png# 查看集合前几行
datas.head()
# 查看数据形状 (行, 列)
datas.shape
# 查看列名
datas.columns
# 每列的数据类型
datas.dtypes
# 设置列为索引
datas.set_index("列名", inplace=True)
# 对列的类型进行转换
datas["列名"].astype("string")
# 查询一列 返回的是pd.Series
datas["列名"]
# 查询多列 返回DataFrame
datas[["列名", "列名"]]
# 查询一行 返回的是pd.Series
datas.loc[1]
# 查询多行 返回DataFrame(包含末尾元素3,且不局限于数字)
datas.loc[1:3]
# 查询所有行&某列 loc[行区间, 列区间]
datas.loc[:, "列名"]
datas.loc[["行1", "行2"], ["列6", "列7"]]
# 条件表达式查询 bool列表长度等于行数或者列数,组合条件时每个都需要加括号
datas.loc[datas["列名"] < 2, :]
datas.loc[(datas["列名"]<2) & (datas["列名"]>-1), :]
# lambda 表达式查询
datas.loc[lambda df: (df["列名"]<2) & (df["列名"]>-1), :]
# 自定义函数查询
def func(df: pd.DataFrame):
return df.index.str.startswith("2022-08") & df["列名"]==xx
datas.loc[func, :]
新增或修改数据列
# 直接赋值
datas.loc[:, "新列名"] = 值
datas.loc[:, "新列名"] = datas["列1"] + datas["列2"]
# apply 新增一列
def func(df):
if df["温度"] > 33:
return "高温"
if df["温度"] < -10:
return "低温"
return "常温"
datas.loc[: "温度类型"] = datas.apply(func, axis=1)
# assign 新增多列 但不改变原始DataFrame
datas = datas.assign(
height_huashi=lambda x: x["高温"] * 9 / 5 + 32,
# 摄氏度转华氏度
low_huashi=lambda x: x["低温"] * 9 / 5 + 32,
)
# 按条件选则分组并赋值
datas["温度类型"] = ""
datas[datas["温度"]>33, "温度类型"] = "高温"
datas[datas["温度"]<-10, "温度类型"] = "低温"
统计函数
# 提取数字列统计结果 (非空行数,平均值,最小值,中位数,最大值等)
datas.describe()
datas["列名"].count()
datas["列名"].max()
datas["列名"].mean()
# 唯一去重
datas["列名"].unique()
# 按值计数
datas["列名"].value_counts()
# 相关系数和协方差
# 如两只股股票是否 同时涨 同时跌, 相关程度多少?正相关还是负相关?
# 协方差矩阵
datas.cov()
# 相关系数矩阵
datas.corr()
datas["空气质量"].corr(datas["高温"])
datas["空气质量"].corr(datas["低温"])
datas["空气质量"].corr(datas["高温"] - datas["低温"])
缺失值处理
# skiprows 读取时 略过两行
studf = pd.read_excel("excel path", skiprows=2)
# isnull notnull isna
studf.isnull()
studf["列名"].isnull()
studf["列名"].notnull()
studf["数字列"].isna()
# 应用
studf.loc[studf["分数"].notnull(), :] # 筛选出分数列不为空的
studf.dropna(axis="columns", how="all", inplace=True) # 删除掉全为空值的列
studf.dropna(axis="index", how="all", inplace=True) # 删除掉全为空值的行
studf.fillna({"分数": 0}) # 分数列为空的填充为0分 等同于 studf.loc[:, "分数"] = studf["分数"].finllna(0)
studf.loc[:, "分数"] = studf["分数"].finllna(method="ffill") # 使用前一个有效值填充
排序
# ascending True 升序 False 降序,inplace 是否修改原 Series
Series.sort_values(ascending=True, inplace=False)
# by = 单个字符串 or 字符串列表
# ascending = 布尔值 or 布尔值数组
DataFrame.sort_values(by, ascending=True, inplace=False)
字符串处理
# 使用前需要获取str属性 即:Series.str
# 是否以某字符串开头(返回为bool)
df["date"].str.startswith("2022-10")
# 链式操作 不能之间.方法 而要先获取 str
df["date"].str.replace("-", "").str.slice(0, 6)
# pandas 默认开启正则表达式
df["中文日期"] = df["中文日期"].str.replace("[年月日]", "")
axis
-
axis=0 或 axis="index"
- 如果是单行操作,则指某一行
- 如果是聚合操作,则指 跨行
-
axis=1 或 axis="columns"
-
如果是单行操作,则指每一列
-
如果是聚合操作,则指 跨列
-
>> 简单理解:按照哪个axis,就证明这个axis要动起来(类似于被for遍历), 其他的axis保持不动
# 对比如下
df.drop("A", axis=1)
df.mean("A", axis=0)
关联语法 merge(相当于SQL的join)
join.pngpd.merge( left
, right
, how
="inner", on
=None, right_on
=None, left_on
=None, right_index
=False, left_index
=False, sort
=True, suffixes
=('_x','_y), copy
=True)
- left,right: 要merge的dataframe或者有name的series
- how: join类型,left、right、outer、inner
- on: join的key, left、right都需要有这个key
- left_on、right_on:df 或者 series 的 key
- left_index、right_index: 使用index而不是普通的column做join
- suffixes:如果列有重名自动添加后缀
users = pd.merge(
dataframe1, dataframe2, left_on="user_id", right="user_id", how="inner"
)
users = pd.merge(
dataframe1, dataframe2, on="user_id"
)
Concat DataFrame合并
pandas.concat
(objs, axis=0, join="outer", ignore_index=False)
- objs:一个列表,类容可以是DataFrame或者Series,可以混合
- axis:默认为0代表按行合并,如果等于1则按列合并
- join:合并的时候索引对其方式,默认是outer join,也可以是inner join
- ignore_index: 是否忽略掉原来的索引,重排索引
DataFrame.append
(ohter, ignore_index=False)
append只能按行合并,是concat按行合并的简写
- other:单个dataframe、series、dict或者列表
- ignore_index: 是否忽略掉原来的索引,重排索引
批量拆分合并
如果不存在就创建目录
path = "文件路径"
import os
if not os.path.exists(path)
os.mkdir(path)
拆分
将文件拆分给多个人
user_names = ["人名1", "人名2", "人名3"]
split_size = datas.shape[0]
df_subs = []
for idx, user_name in enumerate(user_names):
begin = idx * split_size
end = begin + split_size
df_sub = datas.iloc[begin, end]
df_subs.append((idx, user_name, df_sub))
for idx, user_name, df_sub in df_subs:
file_name = f"{path}/file_{idx}_{user_name}.xlsx"
df_sub.to_excel(file_name, index=False)
合并
import os
excel_names = []
for excel_name in os.listdir(path):
excel_names.append(excel_name)
df_list = []
for excel_name in excel_names:
excel_path = f"{path}/{excel_name}"
df_split = pd.read_excel(excel_path)
df_list.append(df_split)
df_marge = pd.concat(objs=df_list)
df_marge.to_excel("xx")
分组
import numpy as np
datas.groupby("enable").max()
# as_index 不产生多级索引
datas.groupby(["列名1", "列名2"], as_index=False).mean()
datas.groupby(["列名1", "列名2"], as_index=False).agg([np.sum, np.mean, np.std])
# 单列数据统计
datas.groupby("列名1")["列名2"].agg([np.sum, np.mean, np.std])
# 多列数据统计
datas.groupby("列名1")["列名2"].agg({"列1": np.sum, "列2": np.mean, "列3": np.std})
# 循环遍历分组
g = datas.groupby("列名1")
for name, group in g:
print(name)
print(group)
# 获取单个分组
g.get_group("分组名")
g.get_group(("分组名1", "分组名2"))