Python之Pandas学习

一、Pandas

  pandas是python+data+analysis的组合缩写,2008年WesMcKinney开发出的库,专门用于数据挖掘的开源Python库,是python中基于numpy和matplotlib的第三方数据分析库,与后两者共同构成了python数据分析的基础工具包,享有数分三剑客之名。
pandas是在numpy基础上实现,其核心数据结构与numpy的ndarray十分相似,但pandas与numpy的关系不是替代,而是互为补充。

二者之间主要区别是:

1.数据结构上:
  numpy的核心数据结构是ndarray,支持任意维数的数组,但要求单个数组内所有数据是同质的,即类型必须相同;而pandas的核心数据结构是series和dataframe,仅支持一维和二维数据,但数据内部可以是异构数据,仅要求同列数据类型一致即可
  numpy的数据结构仅支持数字索引,而pandas数据结构则同时支持数字索引和标签索引

2.功能定位上:
  numpy虽然也支持字符串等其他数据类型,但仍然主要是用于数值计算,尤其是内部集成了大量矩阵计算模块,例如基本的矩阵运算、线性代数、fft、生成随机数等,支持灵活的广播机制
  pandas主要用于数据处理与分析,支持包括数据读写、数值计算、数据处理、数据分析和数据可视化全套流程操作

pandas主要面向数据处理与分析,主要具有以下功能特色:

  • 按索引匹配的广播机制,这里的广播机制与numpy广播机制还有很大不同
  • 便捷的数据读写操作,相比于numpy仅支持数字索引,pandas的两种数据结构均支持标签索引,包括bool索引也是支持的
  • 类比SQL的join和groupby功能,pandas可以很容易实现SQL这两个核心功能,实际上,SQL的绝大部分DQL和DML操作在pandas中都可以实现
  • 类比Excel的数据透视表功能,Excel中最为强大的数据分析工具之一是数据透视表,这在pandas中也可轻松实现
  • 自带正则表达式的字符串向量化操作,对pandas中的一列字符串进行通函数操作,而且自带正则表达式的大部分接口
  • 丰富的时间序列向量化处理接口
  • 常用的数据分析与统计功能,包括基本统计量、分组统计分析等
  • 集成matplotlib的常用可视化接口,无论是series还是dataframe,均支持面向对象的绘图接口

核心数据结构

1、DataFrame

  • 既有行索引,又有列索引的二维数组
  • 行索引,表明不同行,横向索引,叫index
  • 列索引,表明不同列,纵向索引,叫columns

常用属性

  • shape
  • index 行索引列表
  • columns 列索引列表
  • values 直接获取其中array的值
  • T 行列转置

常用方法

  • head() 开头几行
  • tail() 最后几行
import numpy as np
import pandas as pd
# 创建一个符合正态分布的10个股票5天的涨跌幅数据
stock_change = np.random.normal(0, 1, (10, 5))
pd.DataFrame(stock_change)
# 添加行索引
stock = ["股票{}".format(i) for i in range(10)]
pd.DataFrame(stock_change, index=stock)
# 添加列索引
date = pd.date_range(start="20200101", periods=5, freq="B")
data = pd.DataFrame(stock_change, index=stock, columns=date)

# 属性
print(data.shape)
print(data.index)
print(data.columns)
print(data.values)
data.T # 行列转置

# 方法
data.head(3) # 开头3行
data.tail(2) # 最后2行

索引设置

# 修改行列索引值
# data.index[2] = "股票88" 不能单独修改索引
stock_ = ["股票_{}".format(i) for i in range(10)]
data.index = stock_

# 重设索引
data.reset_index(drop=False) # drop=True把之前的索引删除

# 设置新索引
df = pd.DataFrame({
     'month': [1, 4, 7, 10],
                    'year': [2012, 2014, 2013, 2014],
                    'sale':[55, 40, 84, 31]})
# 以月份设置新的索引
df.set_index("month", drop=True)
# 设置多个索引,以年和月份
new_df = df.set_index(["year", "month"])

2、MultiIndex与Panel

2.1、MultiIndex
多级或分层索引对象

  • index属性
    • names: levels的名称
    • levels: 每个level的元组值
print(new_df.index)
print(new_df.index.names)
print(new_df.index.levels)

2.2、Panel

pandas.Panel(data=None,items=None,major_axis=None,minor_axis=None,copy=False,dtype=None)存储3维数组的Panel结构

  • items - axis 0,每个项目对应于内部包含的数据帧(DataFrame)。
  • major_axis - axis 1,它是每个数据帧(DataFrame)的索引(行)。
  • minor_axis - axis 2,它是每个数据帧(DataFrame)的列。
p = pd.Panel(np.arange(24).reshape(4,3,2),
                 items=list('ABCD'),
                 major_axis=pd.date_range('20130101', periods=3),
                 minor_axis=['first', 'second'])
p["A"]
p.major_xs("2013-01-01")
p.minor_xs("first")

注:Pandas从版本0.20.0开始弃用,推荐的用于表示3D数据的方法是DataFrame上的MultiIndex方法

3、Series
带索引的一维数组

属性

  • index
  • values
# 创建
pd.Series(np.arange(3, 9, 2), index=["a", "b", "c"])
# 或
pd.Series({
     'red':100, 'blue':200, 'green': 500, 'yellow':1000})

sr = data.iloc[1, :]
sr.index # 索引
sr.values # 值

总结:DataFrame是Series的容器,Panel是DataFrame的容器

二、基本数据操作

1、索引操作

data = pd.read_csv("./stock_day/stock_day.csv")
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1) # 去掉一些不要的列
data["open"]["2018-02-26"] # 直接索引,先列后行

data.loc["2018-02-26"]["open"] # 按名字索引
data.loc["2018-02-26", "open"]
data.iloc[1, 0] # 数字索引

# 组合索引
# 获取行第1天到第4天,['open', 'close', 'high', 'low']这个四个指标的结果
data.iloc[:4, ['open', 'close', 'high', 'low']] # 不能用了
data.loc[data.index[0:4], ['open', 'close', 'high', 'low']]
data.iloc[0:4, data.columns.get_indexer(['open', 'close', 'high', 'low'])]

2、赋值操作

data.open = 100
data.iloc[1, 0] = 222

3、排序操作

排序有两种形式,一种对内容进行排序,一种对索引进行排序

  1. 内容排序:
      使用df.sort_values(key=,ascending=)对内容进行排序,单个键或者多个键进行排序,默认升序,ascending=False:降序 True:升序
  2. 索引排序:
      使用df.sort_index对索引进行排序
data.sort_values(by="high", ascending=False) # DataFrame内容排序

data.sort_values(by=["high", "p_change"], ascending=False).head() # 多个列内容排序

data.sort_index().head()

sr = data["price_change"]

sr.sort_values(ascending=False).head()

sr.sort_index().head()

三、DataFrame运算

1、算术运算

data["open"].add(3).head() # open统一加3  data["open"] + 3
data.sub(100).head() # 所有统一减100 data - 100
data["close"].sub(data["open"]).head() # close减open

2、逻辑运算

query(expr) expr:查询字符串
isin(values) 判断是否为values

data[data["p_change"] > 2].head() # p_change > 2
data[(data["p_change"] > 2) & (data["low"] > 15)].head()

data.query("p_change > 2 & low > 15").head()

# 判断'turnover'是否为4.19, 2.39
data[data["turnover"].isin([4.19, 2.39])]

3、统计运算

describe()

综合分析:能够直接得出很多统计结果,count,mean,std,min,max等

data.describe()
data.max(axis=0)
data.idxmax(axis=0) #最大值位置

4、累计统计函数

cumsum 计算前1/2/3/…/n个数的和
cummax 计算前1/2/3/…/n个数的最大值
cummin 计算前1/2/3/…/n个数的最小值
cumprod 计算前1/2/3/…/n个数的积

data["p_change"].sort_index().cumsum().plot()

5、自定义运算

apply(func, axis=0)
func: 自定义函数
axis=0: 默认按列运算,axis=1按行运算

data.apply(lambda x: x.max() - x.min())

四、Pandas画图

pandas.DataFrame.plot
DataFrame.plot(x=None, y=None, kind=‘line’)

  • x: label or position, default None
  • y: label, position or list of label, positions, default None
    • Allows plotting of one column versus another
  • kind: str
    • ‘line’: line plot(default)
      -’'bar": vertical bar plot
      -“barh”: horizontal bar plot
      -“hist”: histogram
      -“pie”: pie plot
      -“scatter”: scatter plot
data.plot(x="volume", y="turnover", kind="scatter")
data.plot(x="high", y="low", kind="scatter")

pandas.Series.plot

sr.plot(kind="line")

五、文件读取与存储(常用3种文件类型)

1、CSV

pd.read_csv("./stock_day/stock_day.csv", usecols=["high", "low", "open", "close"]).head() # 读哪些列

data = pd.read_csv("stock_day2.csv", names=["open", "high", "close", "low", "volume", "price_change", "p_change", "ma5", "ma10", "ma20", "v_ma5", "v_ma10", "v_ma20", "turnover"]) # 如果列没有列名,用names传入

data[:10].to_csv("test.csv", columns=["open"]) # 保存open列数据

data[:10].to_csv("test.csv", columns=["open"], index=False, mode="a", header=False) # 保存opend列数据,index=False不要行索引,mode="a"追加模式|mode="w"重写,header=False不要列索引

2、HDF5

read_hdf()与to_hdf()
HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame
pandas.read_hdf(path_or_buf, key=None, **kwargs)

从h5文件当中读取数据

  • path_or_buffer: 文件路径
  • key: 读取的键
  • mode: 打开文件的模式
  • reurn: The Selected object

DataFrame.to_hdf(path_or_buf, key, **kwargs)

day_close = pd.read_hdf("./stock_data/day/day_close.h5")
day_close.to_hdf("test.h5", key="close")

3、JSON

read_json()

pandas.read_json(path_or_buf=None,orient=None,typ=“frame”,lines=False)

  • 将JSON格式转换成默认的Pandas DataFrame格式
  • orient: string,Indication of expected JSON string format.
    • ‘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对象
  • typ: default ‘frame’,指定转换成的对象类型series或者dataframe
 sa = pd.read_json("Sarcasm_Headlines_Dataset.json", orient="records", lines=True)

sa.to_json("test.json", orient="records", lines=True)

六、缺失值处理

如何进行缺失值处理?

  1. 删除含有缺失值的样本
  2. 替换/插补数据

1、如何处理NaN?

1.1、判断是否有NaN

  • pd.isnull(df)
  • pd.notnull(df)

1.2、删除含有缺失值的样本
  df.dropna(inplace=True) 默认按行删除 inplace:True修改原数据,False返回新数据,默认False
1.3、替换/插补数据
  df.fillna(value,inplace=True) value替换的值 inplace:True修改原数据,False返回新数据,默认False

import pandas as pd
import numpy as np
movie = pd.read_csv("./IMDB/IMDB-Movie-Data.csv")
# 1)判断是否存在NaN类型的缺失值
np.any(pd.isnull(movie)) # 返回True,说明数据中存在缺失值
np.all(pd.notnull(movie)) # 返回False,说明数据中存在缺失值
pd.isnull(movie).any()
pd.notnull(movie).all()

# 2)缺失值处理
# 方法1:删除含有缺失值的样本
data1 = movie.dropna()
pd.notnull(data1).all()

# 方法2:替换
# 含有缺失值的字段
# Revenue (Millions)    
# Metascore
movie["Revenue (Millions)"].fillna(movie["Revenue (Millions)"].mean(), inplace=True)
movie["Metascore"].fillna(movie["Metascore"].mean(), inplace=True)

2、不是缺失值NaN

不是缺失值NaN,有默认标记的

# 读取数据
path = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
name = ["Sample code number", "Clump Thickness", "Uniformity of Cell Size", "Uniformity of Cell Shape", "Marginal Adhesion", "Single Epithelial Cell Size", "Bare Nuclei", "Bland Chromatin", "Normal Nucleoli", "Mitoses", "Class"]

data = pd.read_csv(path, names=name)

# 1)替换
data_new = data.replace(to_replace="?", value=np.nan)

# 2)删除缺失值
data_new.dropna(inplace=True)

七、数据离散化

  连续属性的离散化就是将连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数 值代表落在每个子区间的属性值。

为什么要离散化:
  连续属性离散化的目的是为了简化数据结构,数据离散化技术可以用来减少给定连续属性值的个数。离散化方法经常作为数据挖掘的工具。

如何实现数据的离散化
1、分组

  • 自动分组 sr = pd.qcut(data, bins)
  • 自定义分组 sr = pd.cut(data, [])

2、将分组好的结果转换成one-hot编码(哑变量)

  • pd.get_dummies(sr, prefix=)
# 1)准备数据
data = pd.Series([165,174,160,180,159,163,192,184], index=['No1:165', 'No2:174','No3:160', 'No4:180', 'No5:159', 'No6:163', 'No7:192', 'No8:184']) 
# 2)分组
# 自动分组
sr = pd.qcut(data, 3)
sr.value_counts()  # 看每一组有几个数据
# 3)转换成one-hot编码
pd.get_dummies(sr, prefix="height")

# 自定义分组
bins = [150, 165, 180, 195]
sr = pd.cut(data, bins)
# get_dummies
pd.get_dummies(sr, prefix="身高")

八、合并

1、按方向
pd.concat([data1, data2], axis=1) axis:0为列索引;1为行索引

2、按索引
pd.merge(left, right, how=“inner”, on=[]) on:索引

left = pd.DataFrame({
     'key1': ['K0', 'K0', 'K1', 'K2'],
                        'key2': ['K0', 'K1', 'K0', 'K1'],
                        'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({
     'key1': ['K0', 'K1', 'K1', 'K2'],
                        'key2': ['K0', 'K0', 'K0', 'K0'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left, right, how="inner", on=["key1", "key2"])

pd.merge(left, right, how="left", on=["key1", "key2"])

pd.merge(left, right, how="outer", on=["key1", "key2"])

九、交叉表与透视表

找到、探索两个变量之间的关系

1、交叉表
交叉表用于计算一列数据对于另外一列数据的分组个数(寻找两个列之间的关系)

pd.crosstab(value1, value2)

data = pd.crosstab(stock["week"], stock["pona"])
data.div(data.sum(axis=1), axis=0).plot(kind="bar", stacked=True)

2、透视表
DataFrame.pivot_table([], index=[])

# 透视表操作
stock.pivot_table(["pona"], index=["week"])

十、分组与聚合

  分组与聚合通常是分析数据的一种方式,通常与一些统计函数一起使用,查看数据的分组情况。
  DataFrame.groupby(key, as_index=False) key:分组的列数据,可以多个

col =pd.DataFrame({
     'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})

# 进行分组,对颜色分组,price1进行聚合
# 用dataframe的方法进行分组
col.groupby(by="color")["price1"].max()

# 或者用Series的方法进行分组聚合
col["price1"].groupby(col["color"]).max()

你可能感兴趣的:(Python,python,数据挖掘,数据分析)