加载中...

数据分析三大类库的基本使用


numpy

常用方法

import numpy as np
import matplotlib.pyplot as plt
array = np.array([[1,2,3],[4,5,6]])
arr = np.array([1,2,'q'])

img_array = plt.imread('./7.jpg')
plt.imshow(img_array) # 将numpy数组进行可视化展示
img_arraymg = img_array - 100 # 将每一个数组元素减100
plt.imshow(img_arraymg) # 将numpy数组进行可视化展示

np.ones(shape=(3,4))

np.linspace(0,100,20) # 一维等差数列数组

np.arange(10,50,step=2) # 一维等差数列

np.random.randint(0,100,size=(5,4))

常用属性

arr = np.random.randint(0,100,size=(5,4))
arr.shape # 数组形状
arr.ndim # 数组维度
arr.size # 数组元素个数
arr.dtype # 数组元素类型
type(arr) # 数组数据类型
arr = np.array([1,2,3],dtype = 'int32')
arr.dtype
arr.dtype='uint8'
arr.dtype

索引&切片

arr = np.random.randint(0,100,size=(5,4))
arr[0]
arr[0:2] # arr数组前两行
arr[:,0:2] # arr数组前两列
arr[0:2,0:2] # arr数组前两行和前两列的数组
arr[::-1] # arr数组行倒置
arr[:,::-1] # arr数组列倒置
arr[::-1,::-1] #arr数组行列倒置
img_array.shape # 图片行列颜色
plt.imshow(img_array[:,::-1,:]) # 图片倒置
plt.imshow(img_array[200:400,1000:1500,:]) # 图片裁剪

聚合&矩阵

arr.reshape((20,)) # 二维数组->一维数组
arr.reshape((4,5)) # 一维数组->多维
# 级联操作 将多个numpy数组进行横向或纵向拼接
np.concatenate((arr,arr),axis=0) # 0:列
np.concatenate((arr,arr),axis=1) # 1:行
# 图片拼接
img_2 = np.concatenate((img_array2,img_array2,img_array2),axis=0)
plt.imshow(img_2)
  • 常用聚合函数 sum,max,min,mean
arr.sum(axis=1) # 第一列的和
arr.mean(axis=1)
  • 常用数学函数 sin cos tan ,around(a,decimals) a: 数组 decimals:舍入的小数位数,默认为0.如果为负,整数将四舍五入到小数点左侧位置
np.sin(arr)
np.around(3.8) # 四舍五入
  • 常用统计函数
    • numpy.amin() 和 numpy.amax() :用于计算数组中的元素沿指定轴的最小值和最大值
    • numpy.ptp(): 最大值和最小值的差
    • numpy.median(): 计算数组a中元素的中位数
    • 标准差 std() :标准差是一组数据平均值分散程度的一种度量
      • 公式:std = sqrt(mean((x-x.mean())**2))
    • 方差 var() :统计中的方差是每个样本本值与平均数之差平方值的平均数,即标准差就是方差的平方根
arr[1].std()
arr[1].var()
  • 矩阵
a1 = np.array([[2,1],[4,3]])
a2 = np.array([[1,2],[1,0]])
np.dot(a1,a2)
# 运行结果
array([[3, 4],
       [7, 8]])

pandas

Series

  • Series是一种类似于一维数组的对象,由两部分组成
    • values:一维数组
    • index:相关的数据索引标签
  • Series的创建
    • 由列表或numpy数组创建
    • 由字典创建
#%%
from pandas import Series
s = Series(data=[1,2,3,'four'])

#%%

import numpy as np
Series(data=np.random.randint(0,100,size=(3,),dtype='int64'))
#%% 用来指定显示缩影
s = Series(data=[1,2,3,'four'],index=['a','b','c','d'])
s
s.dtype

#%% 为什么需要有显示索引
dic = {
    '语文':100,
    '数学':55,
    '理综':333
}
s = Series(data=dic)
s

#%%

s[0]
s.语文
s[0:2]

#%%
s.shape
s.size
s.index
s.values
s.dtype


#%%

s = Series(data=np.random.randint(60,100,size=(10,)))
s.head(3) # 显示前n个数据


#%%

s.tail(3) # 显示后n个元素

#%%

s.isnull()

#%%

s.notnull

#%%
# Series的算术运算--法则:索引一致的元素进行运算,否则补空
s1  = Series(data=[1,2,3],index=['a','b','c'])
s2  = Series(data=[1,2,3],index=['a','d','c'])
s = s1+s2
s
#%%
s.isnull()

DataFram

  • DataFrame是一个表格型的数据结构,由按一定顺序排列的多列数据组成.既有行索引,也有列索引
    • 行索引:index
    • 列索引:columns
    • 值:values
  • DataFram的创建
    • ndarray创建
    • 字典创建

from pandas import DataFrame
df = DataFrame(data=[[1,2,3],[2,3,4]])
df
#%%

df = DataFrame(data=np.random.randint(10,99,size=(6,4)))
df
#%%

dic = {
    'name':['zhangsna','lisi','wangwu'],
    'salary':[8000,1000,2000]
}
df = DataFrame(data=dic)
df
#%%

df.values
df.columns
df.index
df.shape
df.dtypes

#%%

dic = {
    '张三':[150,150,150,150],
    '李四':[0,0,0,0]
}
df = DataFrame(data=dic,index=['语文','数学','英语','理综'])
df

索引&切片

#%%

from pandas import DataFrame
df = DataFrame(data=[[1,2,3],[2,3,4]])
df
#%%

df = DataFrame(data=np.random.randint(10,99,size=(6,4)))
df
#%%

dic = {
    'name':['zhangsna','lisi','wangwu'],
    'salary':[8000,1000,2000]
}
df = DataFrame(data=dic)
df
#%%

df.values
df.columns
df.index
df.shape
df.dtypes

#%%

dic = {
    '张三':[150,150,150,150],
    '李四':[0,0,0,0]
}
df = DataFrame(data=dic,index=['语文','数学','英语','理综'])
df

#%%

df  = DataFrame(data=np.random.randint(10,99,size=(8,4)),columns=['a','b','c','d'])
df

#%%
# 取单列,如果df有显示的索引,通过索引机制去取行或列的时候只能通过显示索引
df['a']
# 强行使用 行
df.iloc[0]
#%%
# 取多列
df[['a','b']]
# - iloc: 隐式索引取行
# - loc: 显式索引取行
# 取单行
df.iloc[0]
# 取多行
df.iloc[[0,3]]
# 0行3列 单个元素
df.iloc[0,3]
df.loc[0,'c']
# 多个元素
df.iloc[[1,2,3],2]
#%%

# 切行
df[0:2]
# 切列
df.iloc[:,0:2]

运算

  • 同Series

时间数据类型转换

#%%

dic = {
    'time':['2020-10-01','2021-11-11'],
    'temp':[20,30]
}
df = DataFrame(data=dic)
df['time']


#%% 将time列的数据类型转换成时间序列类型
import pandas as pd
df['time'] = pd.to_datetime(df['time'])
df
df['time']


#%% 将time列作为源数据的行索引
df.set_index('time',inplace=True)

df

案例演示

#%%

import pandas as pd
from pandas import Series,DataFrame
import numpy as np
import tushare as ts

#%% 获取某只股票的历史行情数据

df  =ts.get_k_data(code='600519',start='2000-01-01')
df.to_csv('./maotai.csv')

#%%

df = pd.read_csv('./maotai.csv')
df.head()

#%% 删除df指定列

df.drop(labels='Unnamed: 0',axis=1,inplace=True)
df.head()
#%% 查看每一列的数据类型

df.info()
# 将time列转为时间数据类型
df['date'] = pd.to_datetime(df['date'])
df.info()

#%% 将date列作为源数据的行索引
df.set_index('date',inplace=True)
df.head()



#%% 输出该股票所有收盘比开盘上涨百分之三以上的日期

df.loc[(df['close']-df['open'])/df['open']>0.06].index

#%% 输出该股票所有开盘比前日收益跌幅超过2%的日期
(df['open']-df['close'].shift(1))/df['close'].shift(1)<-0.02

# 取出True对应的行数据
df.loc[(df['open']-df['close'].shift(1))/df['close'].shift(1)<-0.02].index
#%% 取出每个月的第一个交易日的第一行数据

new_df = df['2010-01':'2020-02']
df_monthly = new_df.resample('M').first()
#%% 买入股票花费的金额

cost = df_monthly['open'].sum()*100
cost

#%% 卖出股票到手的钱
# 特殊情况 : 2020年买入的股票卖不出去 得切除最后一年的数据
df_yearly = new_df.resample('A').last()[:-1]
resv = df_yearly['open'].sum()*1200
resv
#%% 使用昨天的收盘价作为剩余股票的单价

last_month = 200*new_df['close'][-1]
last_month
#%% 计算总收益

resv+last_month-cost

#%% 双均线策略制定

import pandas as pd
from pandas import Series,DataFrame
import numpy as np
import tushare as ts

#%%

df = pd.read_csv('./maotai.csv')
df
#%% 删除df指定列

df.drop(labels='Unnamed: 0',axis=1,inplace=True)
df['date'] = pd.to_datetime(df['date'])
df.set_index('date',inplace=True)
#%% 5日均线和30日均线

ma5 = df['close'].rolling(5).mean()
ma30 = df['close'].rolling(30).mean()

ma30


#%%
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(ma5[50:180])
plt.plot(ma30[50:180])



#%% 分析输出所有的金叉日期和死叉日期
ma5 = ma5[30:]
ma30 = ma30[30:]
df = df[30:]

#%%
s1 = ma5<ma30
s2 = ma5>ma30
df
# df=df.reset_index()
#%%
death_ex = s1 & s2.shift(1) # 判定死叉条件


death_date = df.loc[death_ex].index # 死叉对应行数据时间



#%%
golden_ex = ~(s1 | s2.shift(1)) # 判定金叉条件
golden_date =df.loc[golden_ex].index # 金叉时间
golden_date

#%%

s1 = Series(data=1,index=golden_date) # 1作为金叉的标识
s2 = Series(data=0,index=death_date) # 0作为金叉的标识
s  =s1.append(s2)
s = s.sort_index() # 金叉和死叉对应的时间
s = s['2010':'2020']
s
#%%
first_money = 100000 # 本金不变
money = first_money # 买卖操作可变的
hold =  0 # 持有股票的数量(100股=1手)
for i in range(0,len(s)):
    if s[i] == 1: # 金叉时间
        time = s.index[i]
        p = df.loc[time]['open'] # 股票单价
        hand_count = money // (p*100) # 最多买多少手股票
        hold = hand_count * 100
        money -=(hold*p)
    else:
        death_time = s.index[i] # 死叉时间
        p_death = df.loc[death_time]['open'] # 卖股票的单价
        money+= (p_death*hold) # 卖出股票的收入
        hold = 0
# 判定最后一天是金叉还是死叉
last_monry = hold*df['close'][-1] # 剩余股票的价值
# 总收益
money+last_monry-first_money

基于pandas的数据清洗

  • 原始数据中存在缺失值(空值)
  • 重复值
  • 异常值

处理丢失数据(空值)

  • 在数据分析中需要使用浮点型的空而不是对象类型的空
    • NAN可以参与运算
    • None不可以参与运算
  • 在pandas中遇到None形式的空值则pandas会将其强转成NAN的形式
#%% 基于pandas的数据清洗
import numpy as np
type(None)
type(np.nan)


#%%

import pandas as pd
from pandas import DataFrame,Series
df = DataFrame(data=np.random.randint(0,100,size=(8,6)))
df.iloc[2,3] = None
df.iloc[4,4] = np.nan
df.iloc[5,5] = None
df
#%% 方式一:对空值进行过滤(删除空所在的行数据)
# isnull notnull any(检测行或列中是否有True) all
df.isnull().any(axis=1)
# 将上部的布尔值作为原数据的行索引
df.loc[df.isnull().any(axis=1)] # true对应的行数据就是存在缺失值的行数据
drop_index = df.loc[df.isnull().any(axis=1)].index # 即将要删除的行索引
df.drop(labels=drop_index,axis=0) # 将缺失行进行删除



#%% all 用来检测false 有false就false

df.notnull().all(axis=1)
df.loc[df.notnull().all(axis=1)]
#%% 方式二--dropna:直接将缺失的行或列进行删除

df.dropna(axis=0)

#%% 对缺失值进行覆盖
# 使用水平和竖直方向的向前向后填充去填充空值
df.fillna(method='ffill',axis=1).fillna(method='bfill',axis=1)

处理重复数据和异常数据

#%% 处理重复数据
df = DataFrame(data=np.random.randint(0,100,size=(8,4)))
df.iloc[2] = [0,0,0,0]
df.iloc[4] = [0,0,0,0]
df.iloc[6] = [0,0,0,0]
df
#%%

df.drop_duplicates(keep='first') # keep = False last

#%% 处理异常数据

df = DataFrame(data=np.random.random(size=(1000,3)),columns=['A','B','C'])
df
# 判定异常条件
twice_std = df['C'].std() * 2
df['C']>twice_std
df.loc[~(df['C']>twice_std)]

DataFrame的级联和合并操作

  • 级联(数据拼接)
#%% DataFram的级联和合并操作

import numpy as np
import pandas as pd
from pandas import DataFrame

#%%

df1 = DataFrame(data=np.random.randint(0,100,size=(5,3)),columns=['A','B','C'])
df2 = DataFrame(data=np.random.randint(0,100,size=(5,4)),columns=['A','B','C','D'])
df1
df2
#%%

pd.concat((df1,df2),axis=0)


#%% 不匹配级联 外连接(outer):补NAN(默认模式) 保证数据的完整性 内连接:只连接匹配的项
pd.concat((df1,df2),axis=0,join='inner')


#%%

df1.append(df2)
  • 合并(数据合并)
  • merge与concat的区别在于,merge需要依据某一共同列来合并
  • 使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并
  • 注意每一列元素的顺序不要求一致
#%% 合并

df1  = DataFrame({'employee':['Bob','jack','lisa'],
                  'group':['Accounting','Engineering','Engineering'],})
df1
#%%
df2  = DataFrame({'employee':['lisa','jack','Bob'],
                  'hire_date':[2018,2020,2021],})
df2


#%%

pd.merge(df2,df1,on='employee' ) # ctrl+p 看参数按情况传递

pandas高级操作

替换操作

#%% 替换操作
df = DataFrame(data=np.random.randint(0,100,size=(5,6)))
df

#%%

df.replace(to_replace=2,value='Two')

#%%

df.replace(to_replace={74:'one'})

#%%
df.replace(to_replace={3:50},value='five ten')

映射操作

  • 创建一个映射关系表,把values元素的和一个特定的标签或者字符串绑定(给一个元素提供不同的表现形式)
#%%

dic = {
    'name':['张三','李四'],
    'salary':[1000,2000]
}
df  = DataFrame(data=dic)
df

#%%

dic  = {
    '张三':'ssm',
    '李四':'shaoshao'
}
df['e_name'] = df['name'].map(dic)
df

#%% 运算工具(求税后薪资)

def salary_after(s):
    return s - (s-500)*0.5
df['after_sal'] =  df['salary'].map(salary_after)
df

排序实现的随机抽样

#%% 排序实现的随机抽样
df  =DataFrame(data=np.random.randint(0,100,size=(100,3)),columns=['A','B','C'])
df


#%% 将原始数据打乱

df.take([2,0,1],axis=1)
# 乱序的随机序列
df.take(np.random.permutation(3),axis=1).take(np.random.permutation(100),axis=0)[0:10]

分组聚合

#%%
df = DataFrame({
    'item':['apple','banan'],
    'price':[3,2],
    'color':['red','yellow'],
    'weight':[12,34]
})
df


#%% 查看详细的分组情况

df.groupby(by='item').groups


#%% 计算每一种水果的平均价格

df.groupby(by='item')['price'].mean()


#%% 将水果根据颜色的平均重量汇总到源数据
dic = df.groupby(by='color')['weight'].mean().to_dict()

df['mean_w'] = df['color'].map(dic)

高级数据聚合(transform apply) 自定义

  • transform apply 也可传入一个lambda表达式
#%% 高级数据聚合(transform apply) 自定义
def my_mean(s):
    m_sum = 0
    for i in s:
        m_sum += i
    return m_sum / len(s)


#%%

df.groupby(by='item')['price'].transform(my_mean)


#%%

df.groupby(by='item')['price'].apply(my_mean)

透视表

  • 透视表是一种对数据动态排布并且分类汇总的表格格式
  • pivot_table 四个重要参数index,values,columns,aggfunc
    • index:分类汇总的分类条件
    • values:对计算的数据进行筛选
    • aggfunc:设置对数据聚合时进行的函数操作,默认aggfunc = 'mean'
    • columns:设置列层次字段
    • fill_value: None->0
df.pivot_table(index=['对手','主客场'],values=['得分','计分板'],aggfunc='sum',columns='对手',fill_value=0)

交叉表

  • 计算分组的特殊透视图,对数据进行汇总
  • `pd.corsstab(index,columns)
    • index:分组数据,交叉表的行索引
    • columns:交叉表的列索引
pd.crosstab(df.smoke,df.sex) # age sex 表中的索引

2012美国大选献金数据分析

#%%

# 导入包
import pandas as pd

#%%

# 读取数据
df = pd.read_csv('./data/2012_Federal_Election_Commission_Database.csv')
df

#%%

# 对新数据进行纵览,查看是否存在缺失数据
df.info()

#%%

# 用统计学指标快速描述属性的摘要
df.describe()

#%%

# 空值处理 -> 将其填充为NOT PROVIDE
df.fillna(value='NOT PROVIDE',inplace=True)
df.info()

#%%

# 异常值处理 将捐赠金额<=0的数据删除
df['contb_receipt_amt'] <= 0
df.loc[df['contb_receipt_amt']<=0]
drop_index = df.loc[df['contb_receipt_amt']<=0].index
df.drop(labels=drop_index,axis=0,inplace=True)
#df.info()
df.loc[df['contb_receipt_amt']<=0]

#%%

print(1)
df.loc[df['contb_receipt_amt']<=0]



#%%

# 异常值处理 将捐赠金额<=0的数据删除
df['contb_receipt_amt'] <= 0
df.loc[df['contb_receipt_amt'] <=0 ]
drop_index = df.loc[df['contb_receipt_amt'] <=0 ].index
df.drop(labels=drop_index,axis=0)

#%%

# 用统计学指标快速描述属性的摘要
df.describe()

#%%

# 空值处理 -> 将其填充为NOT PROVIDE
df.fillna(value='NOT PROVIDE',inplace=True)
df.info()

#%%

# 异常值处理 将捐赠金额<=0的数据删除
df['contb_receipt_amt'] <= 0
df.loc[df['contb_receipt_amt'] <=0 ]
drop_index = df.loc[df['contb_receipt_amt'] <=0 ].index
df.drop(labels=drop_index,axis=0)

#%%

print(1)
df.loc[df['contb_receipt_amt'] <=0 ]

#%%

#通过搜索引擎等途径,获取到每个总统候选人的所属党派,建立字典parties,候选人名字作为键,所属党派作为对应的值
parties = {'Bachmann, Michelle': 'Republican',
           'Cain, Herman': 'Republican',
           'Gingrich, Newt': 'Republican',
           'Huntsman, Jon': 'Republican',
           'Johnson, Gary Earl': 'Republican',
           'McCotter, Thaddeus G': 'Republican',
           'Obama, Barack': 'Democrat',
           'Paul, Ron': 'Republican',
           'Pawlenty, Timothy': 'Republican',
           'Perry, Rick': 'Republican',
           "Roemer, Charles E. 'Buddy' III": 'Republican',
           'Romney, Mitt': 'Republican',
           'Santorum, Rick': 'Republican'}
# 新建一列为各个候选人所在党派的party
df['party']  =df['cand_nm'].map(parties)

#%%

df.head()

#%%

# 查看party这一列有哪些不同的元素
df['party'].unique()

#%%

df['party'].value_counts()

#%%

# 查看各党派收到的政治现金总数contb_receipt_amt
df.groupby(by='party')['contb_receipt_amt'].sum()

#%%

# 查看每天各个党派收到的政治献金总数contb_receipt_amt
df.groupby(by=['contb_receipt_dt','party'])['contb_receipt_amt'].sum()

#%%

months = {
    'JAN':1,'FEB':2,'MAR':3,'APR':4,'MAY':5,'JUN':6,'JUL':7,'AUG':8,'SEP':9
,'OCT':10,'NOV':11,'DEC':12}

#%%

# 将表中的日期改为'yyyy-mm-dd'
def transformDate(d):
    day,month,year = d.split('-')
    month = months[month]
    return '20'+year+'-'+str(month)+'-'+day
df['contb_receipt_dt']  = df['contb_receipt_dt'].map(transformDate)

#%%

df.head()

#%%

# 查看老兵(捐献者的职业) DISABLED VETERAN 主要支持谁 捐钱最多
df['contbr_occupation'] == 'DISABLED VETERAN'
df_old = df.loc[df['contbr_occupation'] == 'DISABLED VETERAN']
# 根据候选人组分,对捐赠金额求和
df_old.groupby(by='cand_nm')['contb_receipt_amt'].sum()

matplotlib绘图

线形图

#%%  matplotlib 绘图

import matplotlib.pyplot as plt
import numpy as np


#%% 绘制线形图

x = np.array([1,2,3,4,5])
y = x + 3

plt.plot(x,y)
plt.plot(x+1,y-2)

#%%

plt.plot(x,y,x+3,y-1)

#%% 设置绘制坐标的比例

plt.figure(figsize=(5,9))
plt.plot(x,y)


#%% 设置图例

plt.plot(x,y,label='x,y')
plt.plot(x+1,y-2,label='x+1,y-2')
plt.legend() # param : ncol=2



#%% 设置轴的标识

plt.plot(x,y)
plt.xlabel('temp')
plt.ylabel('dist')
plt.title('dist and temp')

#%% 图例保存

fig = plt.figure()
plt.plot(x,y,label='x,y')
plt.legend()
fig.savefig('123.png')

#%% 其他样式风格

plt.plot(x,y,c='red',alpha=0.5)

柱状图

#%%

# 柱状图
plt.bar(x,y)
plt.barh(x,y)

直方图

#%%

# 直方图
data = [0,1,1,2,2,2,2,3,3,4,5,6,6,6,7,7,9,8]
plt.hist(data,bins=20)

饼图

#%%

# 饼图 labeldistance 距圆心的距离  autopct 所占的比例
arr = [1,2,3]
plt.pie(arr,labels=['a','b','c'],labeldistance=0.3,shadow=True,explode=[0.2,0.3,0.5],autopct='%0.6f%%')

散点图

#%%

# 散点图
x = np.array([1,3,5,6,7])
y = x**2+2
plt.scatter(x,y)

文章作者: shaoshaossm
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 shaoshaossm !
评论
  目录