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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章