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,就证明这个axis要动起来(类似于被for遍历), 其他的axis保持不动

# 对比如下
df.drop("A", axis=1)
df.mean("A", axis=0)

关联语法 merge(相当于SQL的join)

join.png

pd.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)

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)

DataFrame.append(ohter, ignore_index=False)

append只能按行合并,是concat按行合并的简写

批量拆分合并

如果不存在就创建目录

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"))
上一篇下一篇

猜你喜欢

热点阅读