Python模块之Pandas

Python模块之Pandas part1

基本属性

import pandas as pd
# 形状
df.shape
# 行索引
df.index
# 列索引
df.columns
# 值
df.values
# 转置
df.T
# 前N行 默认是5行
df.head()
# 后N行 默认是5行
df.tail()
# 查看类型
df.dtypes
# 指定类型
df.astype(int)

常用操作

import numpy as np
import pandas as pd

df: pd.DataFrame
    
# 删除指定列 col1, col2
df.drop([col1, col2], axis=1, inplace=True)

# 针对 city name 2列进行去重
df.drop_duplicates(subset=["city", "name"], inplace=True)

# 对Series进行操作 Series.str转成srt 可调用string的方法
df['typecode'].str.endswitch('00') # typecode 以00 结尾
# 对 text 列 使用正则提取 放入rating
df['rating'] = df['text'].str.extract(r'(\d+\.?\d*\/\d+)', expand=False)

# 对1列 拆分成2列
df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2']})
df['A'], df['B'] = df['AB'].str.split('-', 1).str

# 对Series 转成list
df['A'].values.tolist()

索引

# 修改所有行列索引
new_idx = []
new_col = []
df = df(index=new_idx, columns=new_col)

# 修改单个索引 inplace=True 替换原来的
data.rename(index={"0": "股票1", "1":"股票2"}, inplace=True)
data.rename(columns={"city": "cityname", "ccode": "citycode"}, inplace=True)

# 设置新的下标索引
df.reset_index(drop=True)

# 把某列的值设置为索引,设多列 会变成MultiIndex 复合索引 表示多维数据
df.set_inde(keys, drop=True)

取值

# 直接使用行列索引(先列后行)
df["open"][9]  # 单个数据
df[['open', 'close']][1:7]  # 连续行
df[['open', 'close']][df.index.isin([1, 4, 8])]  # 非连续行

# 通过loc 使用索引名 (先行后列)
df.loc["行索引0": "行索引9", "NEW_TYPE":"中类"]

# 通过iloc 使用索引下标 (先行后列)
df.iloc[:3, 1:5]  

运算

# 加减乘除 直接使用算术表达式 或者 使用函数 add/sub/mul/div
df["pop_sum"] = df["pop_1"] + df["pop_2"]

# 逻辑运算 > >= < <= == != 得到bool的结构
df[df["pop_sum"] > 10]

# 与(&)或(|)非(~)
df[(df["pop_1"] > 10) & (df["pop_2"] < 50)]
df[(df["pop_1"] > 10) | (df["pop_2"] < 50)]
df[~df["pop_1"] > 10]

# 传入布尔表达式,进行查询过滤
df.query("pop_1 > 10 & pop_2 < 50")

# 返回布尔结构 可做索引 
df[df["pop_1"].isin([10, 20, 30, 40])]

# 统计运算 返回每列 常见的统计量 非空数量/平均值/标准差/最大值/最小值/中位数/分位数
df.describe()

# 统计运算 默认对列操作, axis=1 对行操作
df.sum()
  • 统计运算(默认对列操作, axis=1 对行操作)
函数 作用(针对非 NaN 值)
sum
mean 平均数
median 中位数
min 最小值
max 最大值
mode 众数
abs 绝对值
prod Product of values
std 标准差
var 方差
idxmax 计算最大值所在的索引
idxmin 计算最小值所在的索引
cumsum 计算前1/2/3/…/n个数的和
cumprod 计算前1/2/3/…/n个数的积
cummax 计算前1/2/3/…/n个数的最大值
cummin 计算前1/2/3/…/n个数的最小值
  • idxmax / idxmin 调用报错
TypeError: reduction operation 'argmax' not allowed for this dtype
  • 从文件中读取数据后, 默认元素类型是object

  • df.dtypes 查询所有列的数据类型

  • 读取时使用dtype 或 读取后使用astype转换

  • pd.to_numeric(s, errors=’’") 转成数值

    • error = ‘raise’ 无效值 报错
    • errors=‘coerce’ 无效值强制转为NaN
    • errors=‘ignore’ 异常值忽略
  • 自定义运算

df.apply(func, axis=0, args=())
 # func: 自定义函数 对行/列进行操作
 # agrs: 函数其他参数
 # axis=0: 默认是列 1为行运算 
  • 排序
# 对值排序 根据单个/多个列,进行排序,默认升序 
df.sort_values(by=[], ascending=True)
# 对索引排序
df.sort_index(axis=0, ascending=True)

IO 操作

读写csv
pd.read_csv(filepath_or_buffer, sep=",", header="infer", names=None,index_col=None, dtype={}, encoding="utf-8", usecols=None)   
  • pd.read_csv()

    • 读取csv 文件
    • filepath_or_buffer: 文件路径
    • sep: 分隔符 默认,
    • header: 指定做列索引的行, 默认是 infer (推断)
    • names: 添加列名. 有列名的情况下 设置 header=0
    • index_col: 指定做行索引的列, 传下标或者列名
    • dtype: 指定类型 指定所有 或 特定几列 dict
    • usecols: 指定读取的列名 list
    • encoding: 编码格式
  • pd.to_csv()

    • 写入 csv
    • path_or_buf: 路径
    • sep: 分隔符, 默认是 ,
    • columns: 指定列
    • index: 是否写入行索引
    • header: 是否写入列索引
    • mode: ‘w’ 重写 ‘a’ 追加
    • encoding: 编码格式
HDF5 一种容器 可以存放多份数据 通过不同的 key来区分比 csv 读写更快 内存更小
  • pd.HDFStore("./test.h5").keys()
    • 获取 test.h5 文件所有的 key
  • pd.read_hdf()
    • 读取 hdf5 文件
    • path_or_buf: 路径
    • key: 读取的键 单份数据 可不输入
    • mode: 打开文件的方式
  • pd.to_hdf()
    • 写入hdf5 文件
    • path_or_buf: 路径
    • key: 必须提供 key
    • mode: 打开文件的方式
读写json
  • pd.read_json()
    • 读取 json 文件
    • path_or_buf: 路径
    • orient: json 文件的数据方式
      • ‘split’ : dict like {index -> [index], columns -> [columns], data -> [values]}
      • ’records’ : list like [{column -> value}, … , {column -> value}]
      • ‘index’ : dict like {index -> {column -> value}}
      • ’columns’ : dict like {column -> {index -> value}},默认该格式
      • ‘values’ : just the values array
    • lines : boolean, default False
      • 按照每行读取json对象
  • pd.to_json()
    • 写入 json
    • path_or_buf: 路径
    • orient: json 文件的数据方式
读取数据库
import pandas as pd
from sqlalchemy import create_engine
 # 使用 sqlalchemy
engine = create_engine(f"mysql+pymysql://{DB_USERNAME}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}")
# 或者 使用 pymysql
import pymysql
db = pymysql.connect(host, port, user, password,database, charset="utf8")
sql = "select * from test_table"
df = pd.read_sql(sql, engine)
# 或者
df = pd.read_sql(sql, db)

缺失值(missing value)处理

缺失值必须是 np.nan

  • 判断缺失值是否存在

    • df.isnull()
      • 配合 np.any() 查看整体是否有空值
    • df.notnull()
  • 找出包含空值的列

    • df.isnull().sum()
      • 为空 返回True 就是 1 累加>0 的列就含有空值
    • df.isnull().apply(np.any)
  • df.dropna(axis=‘rows’)

    • 删除包含空值的行
    • 需要接收返回值
  • df.fillna(value, inplace=True)

    • 替换缺失值(均值/中值)
    • inplace=True 修改原数据
    • 对几列操作 value 传 dict {‘列名’:‘替换值’}
      • df.fillna({‘Live’: 111, ‘Task’:222})

缺失值不为 np.nan 先替换再操作

  • df.replace(’?’, np.nan)

离散化(结果是 Series)

  • pd.qcut(series, bins)
    • 按照给定的分组数量,自动切分series
    • bins 传分组个数 int
  • pd.cut(series,bins)
    • 按照给定的切分点分组
    • bins 需要自定义分组区间 (传 list)
  • pd.get_dummies(data, prefix=None)
    • 创建one-hot 编码
    • data:array-like, Series, or DataFrame
    • prefix:分组名字

合并

  • pd.concat([data1, data2], axis=1)
    • 按照行/列合并 axis=1 按行拼接
  • pd.merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=(’_x’, ‘_y’), copy=True, indicator=False,validate=None)
    • 可以指定按照两组数据的共同键值对合并或者左右各自键合并
    • 基于一个/多个 key 合并(可以将多个 key 先组合视为一个 key 再合并)
    • how: 连接方式
    • left: A DataFrame object
    • right: Another DataFrame object
    • on: Columns (names) to join on. Must be found in both the left and right DataFrame objects.
    • left_on=None, right_on=None:指定左右键
Merge method SQL Join Name Description
left LEFT OUTER JOIN Use keys from left frame only
right RIGHT OUTER JOIN Use keys from right frame only
outer FULL OUTER JOIN Use union of keys from both frames
inner INNER JOIN Use intersection of keys from both frames

交叉透视表

  • pd.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, margins_name=‘All’, dropna=True, normalize=False)
    • 交叉表
    • index: 指定交叉表的行
    • columns: 指定交叉表的列d
    • normalize: 默认为 False, ‘index’ 按行计算比例 ‘columns’ 按列计算比例
  • pd.pivot_table()
    • 透视表
    • index
    • columns
    • values
    • aggfunc=‘mean’ 计算平均值 count 计数

分组与聚合

对 df 做 groupby 生成 DataFrameGroupby 对象

做索引后 生成 SeriesGroupby 对象

  • df.groupby(key, as_index=False)
    • 分组操作
    • Key: 分组的列数据,可以多个
  • 聚合(sum/min/max/count/mean/std/var)
# 对 color 分组 对 price 求平均值
data.groupby(['color'])['price'].mean()
# 写法 2  Series.groupby(Series)  
data['price'].groupby(data['color']).mean()

分类

  • pd.Categorical(values, categories=None, ordered=None, dtype=None, fastpath=False)

    • 数字化分类数据, 有效加快分类计算的效率

    • values: list-like

    • categories: 唯一类别

    • ordered: 是否为有序分类

    • 属性

      • categories: 分类索引
      • codes: 对应的分类后的数组值d
      • ordered: 顺序
      • dtype: 类别
     c = pd.Categorical(['a','b','c','a','b','c'])
     c
     [a, b, c, a, b, c]
     Categories (3, object): [a, b, c]
         
     c.categories
     Index(['a', 'b', 'c'], dtype='object')
     
     c.codes
     array([0, 1, 2, 0, 1, 2], dtype=int8)
     
     c.ordered
     False
     
     c.dtype
     CategoricalDtype(categories=['a', 'b', 'c'], ordered=False)
    
  • pd.factorize(values, sort=False, order=None, na_sentinel=-1, size_hint=None)

    • 转换为枚举或分类类型
    • 返回值
      • labels : ndarray
      • uniques : ndarray, Index, or Categorical
>>> labels, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'])
>>> labels
array([0, 0, 1, 2, 0])
>>> uniques
array(['b', 'a', 'c'], dtype=object)

>>> labels, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'], sort=True)
>>> labels
array([1, 1, 0, 2, 1])
>>> uniques
array(['a', 'b', 'c'], dtype=object)

>>> labels, uniques = pd.factorize(['b', None, 'a', 'c', 'b'])
>>> labels
array([ 0, -1,  1,  2,  0])
>>> uniques
array(['b', 'a', 'c'], dtype=object)

>>> cat = pd.Categorical(['a', 'a', 'c'], categories=['a', 'b', 'c'])
>>> labels, uniques = pd.factorize(cat)
>>> labels
array([0, 0, 1])
>>> uniques
[a, c]
Categories (3, object): [a, b, c]

时间索引

  • pd.to_datetime(arg, errors=‘raise’, dayfirst=False, yearfirst=False, utc=None, box=True, format=None, exact=True, unit=None, infer_datetime_format=False, origin=‘unix’, cache=False)

    • 转换成pandas的时间类型 Timestamp
    • arg : integer, float, string, datetime, list, tuple, 1-d array, Series
    • error: 异常解决办法 {‘ignore’, ‘raise’, ‘coerce’}, default ‘raise’
    • dayfirst : boolean, default False.True 10/11/12 -> 2012-11-10
    • yearfirst: boolean, default False.True 10/11/12 -> 2010-11-12
    • format: 时间戳转为date 格式 %d/%m/%Y
    • unit: 时间戳转 date 的精度 default ‘ns’
    • origin: ‘unix’, 时间原点为 1970-01-01. 可自定义Timestamp 格式,从设置那天算起
    df = pd.DataFrame({'year': [2015, 2016],
                           'month': [2, 3],
                           'day': [4, 5]})
    pd.to_datetime(df)
    0   2015-02-04
    1   2016-03-05
    dtype: datetime64[ns]
    
    pd.to_datetime(1490195805433502912, unit='ns')
    Timestamp('2017-03-22 15:16:45.433502912')
    
    pd.to_datetime([1, 2, 3], unit='D',origin=pd.Timestamp('1960-01-01'))
    0    1960-01-02
    1    1960-01-03
    2    1960-01-04
    
    pd.Timestamp(1513393355.5, unit='s')
    Timestamp('2017-12-16 03:02:35.500000')
    
    # 有空值 结果会变成NaT类型
    dates = ['20200401', '20200402', '20200403', np.nan]
    pd.to_datetime(dates)
    DatetimeIndex(['2020-04-01', '2020-04-02', '2020-04-03','NaT'], dtype='datetime64[ns]', freq=None)
    
  • pd.DatetimeIndex()

    • 与pd.to_datetime 效果一样
  • pd.Timestamp 类型

    • 属性 year,month,weekday,day,hour
    • 属性 .week 获取当前日期对应当前年份第几个星期(从 1 开始)
    • 方法.weekday() 获取当前日期对应星期几(从 0 开始)
  • pd.date_range(start=None, end=None, periods=None, freq=‘D’, tz=None, normalize=False, name=None, closed=None, **kwargs)

    • 生成指定频率的时间序列
    • start:开始时间
    • end:结束时间
    • periods:生成多长的序列
    • freq:频率,默认是D(1天), ‘B’ 工作日
    • tz: 时区
    • close: 默认None 包含start和end, left 只包含start , end 只包含end
    参数 含义
    D 每日
    B 每工作日
    H、T或者min、S 时、分、秒
    M 每月最后一天
    BM 每月最后一个工作日
    WOM-1MON, WOM-3FRI 每月第几周的星期几
  • pd.resample()

    • 频率转换和时间序列重采样,对象必须具有类似日期时间的索引(DatetimeIndex,PeriodIndex或TimedeltaIndex)

      参数 说明
      rule 表示重采样频率,例如周’W’,月’M’,季度’Q’,5分钟’5min’,12天’12D’
      how=’mean’ 用于产生聚合值的函数名或数组函数,例如‘mean’、‘ohlc’、np.max等,默认是‘mean’,其他常用的值由:‘first’、‘last’、‘median’、‘max’、‘min’
      axis=0 默认是纵轴,横轴设置axis=1
      fill_method = None 升采样时如何插值,比如‘ffill’、‘bfill’等
      closed = ‘right’ 在降采样时,各时间段的哪一段是闭合的,‘right’或‘left’,默认‘right’
      label= ‘right’ 在降采样时,如何设置聚合值的标签,例如,9:30-9:35会被标记成9:30还是9:35,默认9:35
      loffset = None 面元标签的时间校正值,比如‘-1s’或Second(-1)用于将聚合标签调早1秒
      limit=None 在向前或向后填充时,允许填充的最大时期数
      kind = None 聚合到时期(‘period’)或时间戳(‘timestamp’),默认聚合到时间序列的索引类型
      convention = None 当重采样时期时,将低频率转换到高频率所采用的约定(start或end)。默认‘end’
  • pd.rolling_mean(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs)

    • 计算移动平均线
    • arg: Series DataFrame
    • window: 计算周期
  • pd.ewma(com=None, span=one)

    • 指数平均线
    • span:时间间隔
  • pd.scatter_matrix(frame, figsize=None)

    • 各项指数两两关联散点图
    • frame:DataFrame
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章