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()
-
找出包含空值的列
- df.isnull().sum()
- 爲空 返回True 就是 1 累加>0 的列就含有空值
- df.isnull().apply(np.any)
- df.isnull().sum()
-
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 objectright
: Another DataFrame objecton
: 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