使用 Pandas 数据分析
pd.Series(np.arange(10)):指定内容,默认索引;pd.Series([1,8,5], index=["a", "b", "c"]):指定索引;pd.Series({'red': 100, 'blue': 200, 'green': 300}):通过字典构造数据;pd.DataFrame(ndarray, index, columns):构造一个 DataFrame;pd.date_range(start="20200101", periods=5, freq="B"):添加日期作为索引; stock_ = ["股票_{}".format(i) for i in range(10)];data.index = stock_data.reset_index(drop=False):drop:False 表示将索引加入到数据中。drop:True 表示直接删掉索引;data.set_index(keys, drop=True): 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']):构造一个三维 Pannel,可以理解成为 DataFrame 容器,直接打印不能展示数据,要通过维度访问; p.major_xs("2013-01-01") 访问该时间维度;p.minor_xs("first") 访问该次序维度;# 创建一个符合正态分布的10个股票5天的涨跌幅数据
stock_change = np.random.normal(0, 1, (10, 5))# 1.构造 DataFrame
## 1.1 通过 ndarray 数组生成
stock = ["股票{}".format(i) for i in range(10)] # 行索引
date = pd.date_range(start="20180101", periods=5, freq="B") # 列索引
data = pd.DataFrame(stock_change, index=stock, columns=date)
## 1.2 通过字典生成
df = pd.DataFrame({'month': [1, 4, 7, 10],'year': [2012, 2014, 2013, 2014],'sale':[55, 40, 84, 31]})
# 1.3修改行列索引
stock_ = ["股票_{}".format(i) for i in range(10)]
data.index = stock_
# 1.4 重设索引
# data.reset_index(drop=False)
# 1.5 设置新索引
df.set_index("month", drop=True) # 以月份设置新的索引
new_df = df.set_index(["year", "month"]) # 设置多个索引,以年和月份
print(new_df.index) # 返回 MultiIndex 可以表示三维数据
# 1.6 MultiIndex
print(new_df.index.names) # levels 的名称
print(new_df.index.levels) # 每个 level 的元组值# 2.构造 Panel
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'])
# 2.1 访问维度
print(p["A"])
p.major_xs("2013-01-01")
p.minor_xs("first")# 3.构造 Series
pd.Series(np.arange(10)) # 指定内容,默认索引;
pd.Series([1, 8, 5], index=["a", "b", "c"]) # 指定索引;
pd.Series({'red': 100, 'blue': 200, 'green': 300}) # 通过字典构造数据;
a = data["open"]["2018-02-26"]b = data.loc["2018-02-26", "open"]c = data.iloc[1, 0]d = data.loc[data.index[0:4] , ['open', 'close', 'high', 'low']]:获取第1天到第4天的 [‘open’, ‘close’, ‘high’, ‘low’];e = data.iloc[0:4 , data.columns.get_indexer(['open', 'close', 'high', 'low'])]data.open = 100:将open列所有值改成100;data["open"] = 100:将open列所有值改成100;data.iloc[1, 0] = 222:修改某个值;data.sort_values(by=["xxx", "yyy"], ascending=False):ascending=False降序,ascending=True升序;data.sort_index();data["yyy"].add(x):yyy 下所有元素值加 x;data1.sub(data2):data1 一一对应减去 data2;data[data["yyy"] > x]:筛选 yyy 下所有值大于 x 的元素;data[(data["xxx"] > n) & (data["yyy"] < m)]:筛选 xxx 下所有值大于 n,并且 yyy 小于 m的元素;data.query("xxx > n & yyy < m"):使用逻辑运算函数;data[data["xxx"].isin([n, m])]:判断 xxx 是否为 n, m;
data.describe():获取常用统计值;data.max(axis=0):获取最大值;data.idxmax(axis=0):获取最大值所在位置;data.cumsum():计算前1/2/3/…/n个数的和;data.cummax():计算前1/2/3/…/n个数的最大值;data.cummin():计算前1/2/3/…/n个数的最小值;data.cumprod():计算前1/2/3/…/n个数的积;data.apply(lambda x: x.max() - x.min());# 1.读取数据
data = pd.read_csv("../../resources/p00_data_mining/stock_day.csv")
# 删除一些列
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)# 2.索引操作
## 2.1 直接索引(先列后行)
a = data["open"]["2018-02-26"]
## 2.2 按名字索引
b = data.loc["2018-02-26", "open"]
## 2.3 按数字索引
c = data.iloc[1, 0]
## 2.4 组合索引
d = data.loc[data.index[0:4] , ['open', 'close', 'high', 'low']] # 获取第1天到第4天的 ['open', 'close', 'high', 'low']
e = data.iloc[0:4 , data.columns.get_indexer(['open', 'close', 'high', 'low'])]# 3.值操作
data.open = 100 # 将open列所有值改成100
data["open"] = 100 # 将open列所有值改成100
data.iloc[1, 0] = 222 # 修改某个值# 4.排序
data.sort_values(by=["high", "p_change"], ascending=False).head() # 对内容进行排序。ascending=False降序,ascending=True升序
data.sort_index()# 5.DataFrame 运算
## 5.1 算数运算
data["open"].add(3).head() # 加法
data.sub(100).head() # 加法
data["close"].sub(data["open"]).head() # 减法## 5.2 逻辑运算
data[data["p_change"] > 2].head() # 例如筛选p_change > 2的日期数据
data[(data["p_change"] > 2) & (data["low"] > 15)].head() # 完成一个多个逻辑判断, 筛选p_change > 2并且low > 15
data.query("p_change > 2 & low > 15").head() # 逻辑运算函数
f = data[data["turnover"].isin([4.19, 2.39])] # 判断'turnover'是否为4.19, 2.39## 5.3 统计运算
data.describe() # 获取常用统计值
data.max(axis=0) # 获取最大值
data.idxmax(axis=0) # 获取最大值所在位置## 5.4 累计统计函数
data["p_change"].sort_index().cumsum().plot() # plot()画图## 5.5 自定义运算
data.apply(lambda x: x.max() - x.min())
pandas.DataFrame.plot(x=None, y=None, kind=‘line’) pandas.Series.plot(kind="line");# 1.读取数据
data = pd.read_csv("../../resources/p00_data_mining/stock_day.csv")
# 删除一些列
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)# 2.画图
#更简易用matplotlib
data.plot(x="volume", y="turnover", kind="scatter")
data.plot(x="high", y="low", kind="scatter")
data['volume'].plot()
pandas.read_csv(filepath_or_buffer, sep=',', delimiter=None, usecols=[], names=[]): # 1.读取数据
data0 = pd.read_csv("../../resources/p00_data_mining/stock_day.csv", usecols=["high", "low", "open", "close"]).head() # 读哪些列
data = pd.read_csv("../../resources/p00_data_mining/stock_day2.csv", names=["open", "high", "close", "low", "volume", "price_change", "p_change", "ma5", "ma10", "ma20", "v_ma5", "v_ma10", "v_ma20", "turnover"]) # 如果列没有列名,用names传入# 2.写入数据
data[:10].to_csv("../../resources/p00_data_mining/test1.csv", columns=["open"]) # 保存open列数据前10行
data[:10].to_csv("../../resources/p00_data_mining/test2.csv", columns=["open"], index=False, mode="a", header=False) # 保存opend列数据,index=False不要行索引,mode="a"追加模式|mode="w"重写,header=False不要列索引
DataFrame.to_csv(filepath_or_buffer, sep=',', columns=None, header=True, index=True, index_label=None, mode='w', encoding=None): Series.to_csv(...)pandas.read_hdf(path_or_buf, key=None, **kwargs) DataFrame.to_hdf(path_or_buf, key, **kwargs))# 1.读取数据
day_close = pd.read_hdf("../../resources/p00_data_mining/day_close.h5")# 2.写入数据
day_close.to_hdf("../../resources/p00_data_mining/test3.h5", key="close")
# 测试
day_close_test = pd.read_hdf("../../resources/p00_data_mining/test3.h5")
pandas.read_json(path_or_buf=None,orient=None,typ=“frame”,lines=False); DataFrame.read_json(path_or_buf=None,orient=None,lines=True);sa = pd.read_json("../../resources/p00_data_mining/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
##主要是path,orient是一种确定索引与数值的对应,以本例来看,列索引就是‘key’,values就是key对应的值
sa.to_json("../../resources/p00_data_mining/test4.json", orient="records", lines=True)
pd.isnull(data):判断数据是否为 nan。一般会结合 any() 函数使用; np.any(pd.isnull(movie)):返回True,说明数据中存在缺失值;pd.isnull(movie).any():返回True,说明数据中存在缺失值;pd.notnull(data):判断数据是否为 nan。一般会结合 all() 函数使用; np.all(pd.notnull(movie)):返回False,说明数据中存在缺失值;pd.notnull(movie).all():返回False,说明数据中存在缺失值;data.dropna(axis='rows', inplace=):删除缺失值; data.fillna(value, inplace=):替换缺失值; data.replace(to_replace="?", value=np.nan):如果缺失值不是 np.nan 时,需要先把缺失值替换成 np.nan,再进行缺失值处理; # 1.读取数据
movie = pd.read_csv("../../resources/p00_data_mining/IMDB-Movie-Data.csv")# 2.判断是否存在缺失值
np.any(pd.isnull(movie)) # 返回True,说明数据中存在缺失值
np.all(pd.notnull(movie)) # 返回False,说明数据中存在缺失值
pd.isnull(movie).any()
pd.notnull(movie).all()# 3.缺失值处理
# 方法1:删除含有缺失值的样本
data1 = movie.dropna()
# 方法2:替换
# 含有缺失值的字段:Revenue (Millions) 和 Metascore
movie["Revenue (Millions)"].fillna(movie["Revenue (Millions)"].mean(), inplace=True)
movie["Metascore"].fillna(movie["Metascore"].mean(), inplace=True)
# 1.读取数据
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)# 2.将缺失值替换成 np.nan
# 1)替换
data_new = data.replace(to_replace="?", value=np.nan)
# 2)删除缺失值
data_new.dropna(inplace=True)data_new.isnull().any() # 全部返回False说明不存在缺失值了
pd.qcut(data, bins):自动分组; pd.cut(data, bins):自定义分组;data.value_counts():统计分组次数。对数据分组一般会与 vaule_counts 搭配使用,统计每组个数;pandas.get_dummies(data, prefix=None); # 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)分组
# 自动分组
sr1 = pd.qcut(data, 3)
# 自定义分组
bins = [150, 165, 180, 195]
sr2 = pd.cut(data, bins)# 查看分组情况
sr1.value_counts()
sr2.value_counts()# 3)转换成one-hot编码
pd.get_dummies(sr1, prefix="height1")
pd.get_dummies(sr2, prefix="height2")
pd.concat([data1, data2], axis=1):axis:0为列索引,列值2;1为行索引,行值2。字段不一致时会产生缺失值 nan;# 1.读取数据
stock = pd.read_csv("../../resources/p00_data_mining/stock_day.csv")p_change = stock["p_change"]# 2.自定义分组
bins = [-100, -7, -5, -3, 0, 3, 5, 7, 100]
sr = pd.cut(p_change, bins)# 3.离散化 one-hot
stock_change = pd.get_dummies(sr, prefix="rise")# 4.处理好的one-hot编码与原数据合并
pd.concat([stock, stock_change], axis=1) # 列索引合并,行值*2
pd.concat([stock, stock_change], axis=0).head()
pd.merge(left, right, how="inner", 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, left, how="left", on=["key1", "key2"])
# 外连接
pd.merge(left, right, how="outer", on=["key1", "key2"])
pd.crosstab(data["value1"], data["value2"]):生成交叉表;data.pivot_table(["value1"], index=["value2"]):生成透视表;# 探究星期数据以及涨跌幅是好是坏数据# 1.读取数据
stock = pd.read_csv("../../resources/p00_data_mining/stock_day.csv")# 2.准备数据
# 星期数据:pandas日期类型
date = pd.to_datetime(stock.index)
stock["week"] = date.weekday
# 涨跌幅数据
stock["pona"] = np.where(stock["p_change"] > 0, 1, 0)# 3.交叉表
data = pd.crosstab(stock["week"], stock["pona"])
# 3.1 做除法后画图
data.div(data.sum(axis=1), axis=0).plot(kind="bar", stacked=True)# 4.透视表操作
stock.pivot_table(["pona"], index=["week"])
data.groupby(by="yyy", as_index=False):DataFrame 方式进行分组。按 yyy 进行分组;data["xxx"].groupby(data["yyy"]):Series 方式进行分组。效果同上;data.groupby(by="yyy", as_index=False)["xxx"].max():按 yyy 进行分组,然后输出每组 xxx 中的最大值;data["xxx"].groupby(data["yyy"]):效果同上,先根据标签拿到 Series,再进行分组;# 1.准备数据
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]})# 2.分组+聚合:进行分组,对颜色分组,price1进行聚合
# 2.1 用dataframe的方法进行分组
col.groupby(by="color")["price1"].max()
# 2.2 Series 方式进行分组
col["price1"].groupby(col["color"]).max()