Python数据分析常用方法手册
1. Python数据处理和分析常用语句
数据分析的一般步骤包括数据获取、数据整理、数据描述、数据分析
1.1 数据获取
1.1.1 数据获取方式
1.1.2 查看数据属性
Data.shape 查看数据多少行、多少列
Data.columns 查看数据列
Data.dtypes 查看各数据字段的属性
1.2 数据整理
#第二步:做一些数据的基本处理:
1.2.1 数据基本处理(类excel)
#0.数据类型的转换
例如:如果要做时间序列分析,首先要将交易日期从通用对象(object)转换为日期对象(datetime)
df['date'] = pd.to_datetime(df['date'])
#1.如何获取导入的数据有几行几列?
直接用df.shape,返回一个维度(几行,几列)的元组;
df.columns.size #获取列数
df.iloc[:, 0].size #获取行数
#2.如何查看指定行、列、子集?
#df = pandas.read_excel('1.xls',sheetname= '店铺分析日报')
df = df.loc[:,['股票代码','股票名称', '营业总收入']]#访问指定的列
#df=df['股票代码'] #查看指定列
#DataFrame.ix['index_name'] #查看指定行
#dataframe[m:n] #选择多行
#dataframe[dataframe['col3'>5]] #条件筛选
#dataframe.ix[0:3,0:5] #选择子集
#3.如何添加新的列
例1:添加一个总和栏来显示Jan、Feb和Mar三个月的销售总额
df['total'] = df['Jan']+df['Feb']+df['Mar']
例2:把计算结果添加为一个新的列
df['P/E'] = df.收盘价/df.基本每股收益#新的列名,后面是对应的数值
例3:在excel表最后加一行求各列和
sum_row=df[['Jan','Feb','Mar','total']].sum()
#4.如何删除行列
#df_delete=df.drop(['result'],axis=1) #删除列
#DataFrame.drop(['index1','index2'...]) #删除行
#5.如何对数据进行排序?
df['P/E'].size #获取‘P/E’这列共有多少行
newdf=df_delete.sort('P/E') #默认升序排列
sort_index也可以进行排序
#6.如何对数据进行筛选?
#1.筛选出predictaqi_norm1这一列大于100的行;
aqicsv[aqicsv["predictaqi_norm1"]>100]
也可以写为:data[data.收盘价>100]
#2.使用&(并)与| (或)实现多条件筛选
aqicsv[(aqicsv["FID"]>37898) & (aqicsv["FID"]<38766) ]
aqicsv[(aqicsv.predictaqi_norm1>150) |(aqicsv.predictaqi_norm1<100) ]
#3.筛选后取另外两列数据
如果只需要其中两列数据,而同时利用另外两列进行筛选时可以这样.如果只需要其中的某几列可以写为aqicsv[['FID','x','y']]
aqicsv[['x','y']][(aqicsv.FID >10000) | (aqicsv.predictaqi_norm1 >150)]
#4.isin()用法:筛选某一列数据符合等于规定值
(它使得我们可以定义一个列表,里面包含我们所希望查找的值);
data7=data[data['股票代码'].isin(['sh600141','sh600754','sh603017','sh603198'])]
#同样,以上这个语句可以用query()函数来查询,需要安装numexpr;
data8=data.query('股票代码== ['sh600141','sh600754','sh603017','sh603198']')
#map()函数也有这个功能,样式如下:
df[df["sku"].map(lambda x: x.startswith('B1')) & (df["quantity"] > 22)].head()
#5.字符串方法:筛选某一列内容包含特定值
例如找出MA金叉死叉列所有含金叉的行,但列不能含空值
data8=data7[data7['MA金叉死叉'].str.contains('金叉')]
#6.如果列中存在空值,空值处理方法:
#6.1 用fillna()方法将空值填充
data7=data.fillna(value='你好')
#6.2 或者将列中的空值删除;
stock_data = stock_data[stock_data['市盈率TTM'].notnull()]
#或6.2 用dropna删除缺失值
stock_data.dropna(subset=['下个月涨跌幅'], inplace=True)
#7.pandas能够理解日期,在对日期数据筛选方面可以对某年、某月进行筛选;
data[data['交易日期']='2014-03']
data[data['交易日期']='2015']
data[(data['交易日期'] >='20140701') & (data['交易日期'] <= '20140715')].head()
#8.对时间序列数据,设置交易日期为新的索引
df2 = data.set_index(['交易日期'])
#通过切分来获得一段区间
df2["20140101":"20140201"]
df2['2014']
df2['2014-Dec']
#9.用unique()函数来获取一个不含重复项的小列表
df["name"].unique()
#如果这个小列表同时要包含其他列信息,可以用drop_duplicates()函数
df.drop_duplicates(subset=["account number","name"]).head()
#7.数据转置
df_sum=pd.DataFrame(data=sum_row).T
#8.简单的统计与筛选
1.2.2 将分割数据读取到一张DataFrame
# 第五步:数据跟文件夹的交互——读取、保存
#1.用for循环和append函数将文件夹中不同表格的数据经过筛选后加载到同一张表格
import pandas as pd
import os
stock_code_list=[]
for root,dirs,files in os.walk('overview-data-sh/'):
if files:
for f in files:
if'sh6'in f:
stock_code_list.append(f.split('.csv')[0])
all_stock_sh=pd.DataFrame()
for code in stock_code_list:
stock_data=pd.read_csv('overview-data-sh/'+code+'.csv',encoding='gbk')
stock_data=stock_data[['交易日期','股票代码', '股票名称','涨跌幅', '成交额', '换手率', '流通市值','市盈率TTM', '市销率TTM', '市现率TTM', '市净率', 'MA_5', 'MA_10','MA_20', 'MA_30', 'MA_60','MA金叉死叉','MACD_金叉死叉','KDJ_金叉死叉','收盘价','开盘价']]
stock_data['交易日期'] = pd.to_datetime(stock_data['交易日期'])
stock_data=stock_data[stock_data['交易日期']=='2016/9/30']
all_stock_sh=all_stock_sh.append(stock_data,ignore_index=True)
all_stock_sh.shape
#2.用pd.concat将不同文件夹中数据加载到一个DateFrame #3.数据保存
all_stock_sh.to_csv('全部股票当天市场数据20160930sh.csv',encoding='gbk')
1.3 数据描述
1.3.1 绘图与可视化
%pylab
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data=pd.read_csv('sh600000.csv',encoding='gbk')
data1=data['收盘价']
data2=data['交易日期']
# 在一张figure里面画多张图
fig=plt.figure()
ax1=fig.add_subplot(221)
ax1.plot(data1,'g')
# 设置X轴,Y轴,标题
ax1.set_xlabel('Time')
ax1.set_ylabel('Price')
ax1.set_title('my first matplotlib plot')
ax1.set_xlim([data['交易日期']])
# 时间序列趋势图-设置label
如果要在同一个图中显示多个label,可以用plt.legend()函数
代码:
%pylab
import matplotlib.pyplot as plt
import pandas as pd
data=pd.read_csv('overview-data-sh/sh600005.csv',encoding='gbk')
data.交易日期=pd.to_datetime(data.交易日期)
data1=data.set_index('交易日期')['收盘价'].ix['2009']
data2=data.set_index('交易日期')['开盘价'].ix['2009']
plt.title('Trend')
plt.xlabel('Time')
plt.ylabel('Price')
plt.plot(data1,'k',label='1')
plt.plot(data2,'g',label='2')
plt.legend() #用legend()函数可以在一张图里显示多个label plt.show()
# 饼图
plt.subplot(233)
x = [1,2,3,4,5]
y = [2.3,3.4,1.2,6.6,7.0]
scatter(x,y)
# 保存
savefig("demo.png")
例子:绘制股价的时间序列图
Pandas最基本的时间序列类型是以时间戳(Datatimeindex,Periodindex)为索引的Series。Set_index()方法将时间列(column)设置为index
data=data.set_index(['Unnamed: 0'])
https://www.360docs.net/doc/7d1923455.html,='time'
将index转为datatimeindex
data.index=pd.to_datetime(data.index)
data=data.resample('B',fill_method='ffill')
代码:
#利用Python绘制时间序列图
%pylab
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data=pd.read_csv('sh600000.csv',encoding='gbk')
data=data[['收盘价','交易日期']]
data=data.set_index(['交易日期'])
data.index=pd.to_datetime(data.index)
data=data.resample('M',fill_method='ffill')
fig=plt.figure()
ax1=fig.add_subplot(211)
ax1.plot(data,'g')
ax1.set_xlable('Time')
ax1.set_ylable('Price')
ax1.set_title('my first matplotlib plot')
1.4 数据分析
1.4.1 数据聚合与分组运算
#1.groupby技术
from pandas import DataFrame,Series
import numpy as np
df=DataFrame({'key1':['a','a','b','b','a'],
'key2':['one','two','one','two','one'],
'data1':np.random.randn(5),
'data2':np.random.randn(5)})
#1.1 按照key1进行分组,计算data1的平均值mean?
grouped=df['data1'].groupby(df['key1']).mean()
或者:index_datas=index_datas.groupby('股票代码').count()
#1.2 按照key1进行分组,计算data1、data2的平均值? df.groupby(['key1']).mean()
#1.3 按照key1进行分组,计算data1、data2求和?
means=df.groupby(['key1','key2']).sum()
means.unstack() #用unstack()来取消堆叠/拆分列
#1.4 选取部分列进行聚合
means_data1=df.groupby(['key1','key2'])[['data2']].mean()
#或means_data1=df.groupby(['key1','key2'])['data2'].mean()
#或means_data1=df['data2'].groupby([df['key1'],df['key2']]).mean()
#1.5 如何向DataFrame添加一个列
tips['tip/total_bill']=tips['tip']/tips['total_bill']
tips.count() #获取每个column共有多少列
#或者用tips.iloc[:].size #获取共有多少列
#1.6 找出tips1里面,tip大于10的,并降序排列?
tips_10=tips[tips.tip>6].sort('tip',ascending=False)
#1.7 对列sex分组后,对另一列(tip/total_bill)进行排序
def top(self,n):
return self.sort('tip/total_bill',ascending=False)[:n]
#top(tips)
tips.groupby(['sex']).apply(top,n=5)
#1.8 按照某一列内容的部分字母进行分组排序
比如,某一列由不同星期+日期组成,但只想按照这一列的星期进行排序?
#get_day=lambda day: tips.day[:1] # 选择列中的第一个字母,按第一个字母排序#tips.groupby(get_day).apply(top,n=5) #groupby 可以调用函数
#1.9 采用多个聚合函数返回多个聚合值
tips2=tips1.groupby(['sex','smoker'])['total_bill','tip']
tips2.agg(['mean','sum','std','max'])
#2.0 计算tip和total_bill之间的相关系数
#corr=lambda x: x.corrwith(x['tips'])
tips_corr=tips.groupby(['sex'])
tips_corr.apply(lambda g: g['tip'].corr(g['total_bill']))
#2.1 根据日价格变化计算各股票之间的年度相关系数
by_year=data.groupby(lambda x:x.year)
corr=lambda x: x.corrwith(x['SPX'])
data_by_year=by_year.apply(corr)
2.merge 合并
1.Append
P=
2.Concat
例子1:使用concat()函数将两个不同逻辑结构的对象能连接:
将股票数据中的前5个和后5个合并;
Data1=data[:3]
Data2=df[:3]
Pd.concat([Data1,Data2],ignore_index=Ture)
例子2:将两个相同逻辑结构的对象能连接
import pandas as pd
dates=range(20161010,20161020)
pieces=[]
for date in dates:
path='overview-push-%d/stock overview.csv' % date
date=pd.read_csv(path,encoding='gbk')
pieces.append(date)
datas=pd.concat(pieces)
3.Join
将美国运通公司和可可可乐公司近一年中每个月的交易总量表(包含公司代码)与30只道琼斯成分股股票信息表合并;
Pd.merge(data1,data2,on='code')
3.聚类分析
3.1K-均值聚类
scikit-learn 语言包
#K-Mean聚类的一个小例子
from pylab import *
from scipy.cluster.vq import *
list1=[88,64,96,85]
list2=[92,99,95,94]
list3=[91,87,99,95]
list4=[78,99,97,81]
list5=[88,78,98,84]
list6=[100,95,100,92]
data=vstack((list1,list2,list3,list4,list5,list6))
centroids,_=kmeans(data,2)
result,_=vq(data,centroids)
print (result)