python pandas

Series、DataFrame:Series可以当成1维数组

from pandas import Series 

a= Series(data=[1,2,3,'four'])

a= Series(data=[1,2,3,'four'],index=['a','b','c','d'])

dic = {‘chinese’:99,‘math’:100,‘pe’:98}

a= Series(data=dic)

a[0:2]    # 切片

a.shape

a.size                # 返回大小

a.index               #返回索引

a.values              # 返回值

a.dtype               # 返回类型 

Series常用的方法

head()、# 前n个数据

tail()、   # 后n个数据

unique()、# 去重

isnull()、   # y用于判断每一个元素是否为空,为空返回true,否则返回false

notnull()、 # y用于判断每一个元素是否不为空,不为空返回true,否则返回false

add()、sub()、mul()、div()    # 加减乘除

Series算术运算

a+b 

DataFrame

是一个二位数组。

行索引:index、列索引:columns、值:values,shape:维度

初始化

df = DataFrame(data = [[1,2,3],[4,5,6]])

df = DataFrame(data = np.random.randint(0,100,size=(6,4)))

dic = {

”name":["zhangsan","lisi","wanglao"],

"salary":[1000,2000,3000]

}

df = DataFrame(data=dic,index=["a","b","c"])

df[0].dtype

df= DataFrame(data=np.random.randint(60,100,size=(8,4)),columns=["a","b","c","d"])

df["a"]   # 取单列,如果df有显示的索引,通过索引机制去行或者列的时候只可以使用显示索引。

df[['a','c']]       # 取多列

df.iloc[0]         #取单行

df.iloc[[0,2,5]]    #取多行

  • iloc : 通过隐式索引取行
  • loc : 通过显示索引取行

df.iloc[0,2]    #取单个元素,第0行,2列的值。

df.loc[0,‘a’]    #取单个元素.

df.iloc[[1,3,5],2]    #取多个元素.

  

切片

df[0:2]     # 切行, 0、1 行的数据

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

df 索引和切片操作

        索引:

                df[col]:取列

                df.loc[index]:取行

                df.iloc[index,col]:取元素

                df[index1:index3]:切行

                df.iloc[:,col1:col3]:切列

运算:同series 相同

dic = {

”name":["zhangsan","lisi","wanglao"],

"salary":[1000,2000,3000],

"time":['2024-1-1','2024-2-1','2024-3-1']

}

df = DataFrame(data=dic,index=["a","b","c"])

df.loc['zhangsan','salary'] = 3500

df['salary'] += 100

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

# 将time 列作为源数据的行索引

df.set_index('time',inplace = True)

分析

股票分析

-- 聚宽, 也有很多金融数据

- -tushare: 财经数据接口包, 可以上官网看

pip install tushare

import tushare as ts

import pandas as pd

import numpy as np

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

df = ts.get_k_data(code=''600519",start='2000-01-01')

# 将数据存储过本地

df.to_csv("./maotai.csv")

# 将本地的存储的数据读到df

df = pd.read_csc("./maotai.csv")

df.head()

# 删除df 中指定的一列 

df.drop(labels="Unamed:0", axis =1,inplace =true)

# 查看每一列数据类型

df['date'].dtype

df.info()

# 将time转换为时间序列

df["date"] = pd.to_datetime(df["date"]) 

df.set_index("date", inplace=true)

# 输出该股票所有收盘比排盘上涨3%以上的日期,(收盘-开盘)/开盘>0.03

df2 = (df[“close”] - df['open'])/ df['open'] >0.03

# 在分析过程中如果产生了boolean 值,则下一步可作为源数据的行索引

df.loc[df2 ].index                             #  过滤后的行数据的索引

# 输出该股票所有开盘比前日收盘跌幅超过2% 的日期, shift() ,是数据下移

df.loc[(df[“open”] - df['close'].shift(1))/ df['close'].shift(1) <  -0.02].index   

# 需求:假如从 2010-1-1 开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,至今为止,总收益是多少?  2010-2020

1手股票:100 支股票

 new_df = df['2010-01':'2020-02']

# 买股票:找每个月的第一个交易日对应的行数据(),即每月的第一行数据

df_month = new_df.resample('M').first()   # 数据的重新取样,知识点:resample

  

# 买入股票花费的总金额

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

#卖出股票到手的钱

df_year = new_df.resample('A').last()[:-1]       # 注意最后一年的数据要去掉,还没有到年末

# 卖出到手的钱

resv = df_year['open'].sum()*1200

# 手中剩余股票,需要估价,计算到总收益中

left_amount= 200 * new_df['close][-1]

#计算总收益

resv  +  left_amount -cost 

# 双均线策略制定,引用上方的 new_df

计算该股票的历史数据的5日均线和60日均线, 5、10、30、60、120、240

# 均线的计算方法: MA = (C1+C2+C3+...+Cn)/N  ,C是某日收盘架,N是移动平均周期(天数)

# 均线的计算方法:

MA5 = df['close'].rolling(5),mean()       # 计算5日的均值

MA30 = df['close'].rolling(30),mean()       # 计算5日的均值

import matplotlib.pyplot as plt %matplotlib inline

plt.plot(ma5[:30])

plt.plot(ma30[:30])

# 分析出所有金叉和死叉日期

金叉: s1 = ma5<ma30        s2 = ma5 > ma30

ma5 = ma5[30:]

ma30 = ma30 [30:]     # 因为前30 是Non值

s1 = ma5<ma30       

s2 = ma5 > ma30

death_ex = s1 &s2.shift(1)    # 判定死叉的条件

df.loc[death_ex].index

golden_ex = ~(s1 | s2.shift(1) )   # 判定金叉的条件

golden_date = new_df.loc(golden_ex ).index

# 如果冲2010-1-1 开始,初始资金为 100000元,金叉尽量买入,死叉全部卖出,则到今为止,总收益是如何?

 s1 = Series(data=1,index = golden_date)   # 1作为金叉的标识

 s2 = Series(data=0,index = death_date)   # 0作为死叉的标识

a = s1 .append(s2)

s = s.sort_inex() # 存储的是金叉和死叉的对应的时间

s = s['2010':'2020']

first_money = 10000

money = first_money

hold = 0

for i in s:

        if i == 1:   # i =0 (死叉:卖),=1(金叉:买)

                time = s.index[i]

                p = df.loc[time]['open']100       # 股票单价

                hand_count = mone // (p*100)

                hold = hand_count *100

                 money -= (hand_count *100 *p)                # 减去卖股票的money

        else:

                death_time = death_time = s.index[i]

                p = df.loc[time]['open']      # 股票单价

                money += (hand_count *100 *p) 

                hold = 0

# 如何判定最后哦一天金叉还是死叉

last_money = hold * df['close'][-1]   

#总收益

money -   last_money - first_money

数据清洗

  • 原始数据中会存在缺失值
  • 重复值
  • 异常值
处理丢失的数据

有两种丢失数据:

  • None,  type(None)        NoneType
  • np.nan(NaN) ,   type(np.nan)   float

区分:NAN可以参与运算,None 是不可以参与运算的。

在pandas中,如果遇到None,则会将其强转成NAN

np.nan +1   = nan

isnull、notnull、any、all、dropna、fillna

规律:isnull >> any ,notnull >>all

方式1:对空值进行过滤(删除空所在的行数据)

        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)   # 将缺失行进行删除

dropna :直接删除缺失的行或列

df.dropna(axis=0)

fillna

df.fillna(value=666)

df.fillna(method='ffill', axis=0)  #method: ffill 、bfill    # 使用水平方向进行填充

处理重复数据

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[5] =[0,0,0,0]

df.drop_duplicates(keep='first')    # 去掉重复数据,keep='last', keep = False

处理异常数据

级联操作

pd.concat、pd.append

pandas使用pd.concat函数,与np.concatenate 函数类似,只是多了一些参数:

  • objs
  • axis=0
  • keys
  • join='outer' ,'inner':表示的是级联的方式,outer 会将所有的项进行级联(忽略匹配和不匹配),而 inner 只 ignore-index =False。

匹配级联

df1 = pd.DataFrame(data=np.random.randint(5,3),columns=['A','B','C'])

df2 = pd.DataFrame(data=np.random.randint(5,3),columns=['A','D','C'])

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

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

不匹配级联

如果想保留数据的完整性,必须使用outer(外连接)

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

pd.concat((df1,df2),axis=0,join='inner')

append 函数的使用

df1.append(df2)

合并操作

merge与concat 的区别在于,merge 需要依据某一共同列进行合并

使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。

注意每一列元素的顺序不要求一致。

df1 = DataFrame({"emlployee":["Bob","Jake","Lisa"],"group":["Accounting","Engineer","Teacher"]})

df2 = DataFrame({"emlployee":["Lisa","Jake","Bob"],"hire_date":["2021","2020","2009"]})

pd.merge(df1,df2,on="emlployee")

pd.merge(df1,df2,left_on="df1col",right_on="df2col",how="outer")

人口分析

# 为找到这些state/region 的state上补上正确的值,从而去掉state的所有NaN

# 1、先给USA的全称对应的空值进行批量赋值

df1["state/region"]=='USA'

df1.loc[df1["state/region"]=='USA']     # 将usa对应的行数据取出

indexs = df1.loc[df1["state/region"]=='USA'].index

df1.iloc[indexs,"state"]  = ”United States“

# 合并各州面积areas

pd.merge(df1,dfarea,how="outer")

# 去除含有缺失数据的行

df1.drop(labels=indexes,axis=0,inplace=True)

# 找出2010年的全民人口数据

df1.query('ages=="total" & year ==2010')

#人口密度

df1["密度"] = df1["人口数量"] / df1["面积"]

#排序

df1.sort_values(by="密度",axis=0,ascending=False).iloc[0]

pandas高级操作

替换操作

df.replace(to_replace=2,value ="two")    #  把数据中整数 2替换 成”two“

df.replace(to_replace={1:"two"})         #  把数据中整数 2替换 成”two“

df.replace(to_replace={4:5},value="five")         #  把数据中 4 列的 5 替换成”five“

映射

dic = {

”name“:["张三","李四","张四"],

"salary":[14000,15000,18000]

}

df = DataFrame(data=dic)

# 映射关系表

dic2 = {

"张三":"tom",

"李四":"jack"

}

df["engname"]  = df["name"].map(dic)

map是series的方法,只能被series调用。

运算工具

# 该函数是我们指定的一个运算法则

def after_sal(s):

        return s - (s-3000)*0.5

df["after_sal"] = df["salary"].map(after_sal)   # 可以将df["salary"] 这个series中每一个元素作为参数计算

排序实现的随机抽样

  • take()
  • np.random.permutation()

df = DataFrame(data= np.random.randint(0,100,size=(100,3),columns=["A","B","C"] ))

# 生成乱序的随机序列

np.random.permutation(10)

df.take([2,0,1],axis=1)    # 将原始数据打乱

df.take(np.random.permutation(3),axis=1)    # 将原始数据打乱

df.take(np.random.permutation(3),axis=1).take(np.random.permutation(100),axis=0) [0:50]

数据的分类处理

核心:

  • groupby()函数
  • groups属性查看分组情况
dic={
    "item":["apple","banana","orange","banana","orange","apple"],   
    "price":[4,3,3,2.5,4,2],
    "color":["red","yellow","yellow","green","green","green"],
    "weight":[12,20,50,30,20,44] 
}
df = pd.DataFrame(data= dic)

df.groupby(by="item").groups     # 查看详细的分组情况

# 想要水果重量进行分析

df.groupby(by="item").mean()          # 查看字段是数字类型的平均值

df.groupby(by="item")["price"].mean()    # 查看平均价

# 将计算出的平均重量汇总到源数据

avgprice_dict = df.groupby(by="item")["price"].mean().to_dict()

df["color"].map(avgprice_dict )

高级数据聚合

def func(s):

        pass

        return

df.groupby(by="item")["price"].apply(func)

交叉表和透视表

数据加载

# 读取txt文档

pd.read_csv(".xxx.txt")   # 数据少了1行,第一行是columns

pd.read_csv(".xxx.txt",header=None,sep='-')   # 所有数据都是data

#读取sqllite3

import sqlite3 as sqlite3

conn = sqlite3.connect("./data/aa.sqlite")

sql_df = pd.read_sql("select* from tbla",conn)

# 将一个df中的数据值写入存储到db

df.to_sql("tbla",conn)

透视表

透视表是一种可以对数据动态排并且分类汇总的表格格式。或许大多数都在excel使用过透视表,在pandas中他被称作pivot_table.

透视表的优点:

  • 灵活性高,可以随意定制你的分析计算要求
  • 脉络清晰易于理解数据
  • 操作性强,报表神器

df

pivot_table 有四个最重要的参数:index、values、columns、aggfunc

index:分类汇总的分类条件。每个pivot_table必须拥有一个index。

df.pivot_table(index=["对手","主客场"])   # 查看哈登对阵同一对手再不同主客场下的数据,分类条件为 对手、主客场,计算其各类得分的品均值。

# values :需要对计算的数据进行筛选。如果只需要哈登在主客场和不同胜负情况下的的得分、篮板、助攻三项数据。

df.pivot_table(index=["主客场","胜负"],values=["得分","篮板","助攻"]) 

Aggfunc参数:设置对数据聚合时进行的函数操作。当未设置时,默认aggrunc="mean"计算品均值。

df.pivot_table(index=["主客场","胜负"],values=["得分","篮板","助攻"],aggfunc="sum")

 

# 获取每个队主客场的总得分,在总得分的基础上进行了对手的分类

df.pivot_table(index=["主客场"],values="得分",aggfunc="sum",fill_value=0)

df.pivot_table(index=["主客场"],values="得分",columns="对手",aggfunc="sum",fill_value=0)

交叉表

交叉表时一种用于计算分组的特殊透视图,对数据进行汇总

pd.crosstab(index,columns)

  • index:分组数据,交叉表的行索引
  • columns:交叉表的列索引

# 求出各个性别抽烟的人数

pd.crosstab(df.smoke,df.sex)

pd.crosstab(df.age,df.sex)

示例:美国大选分析

# 对信息数据进行总览,查看是否存在缺失数据

df.info()

#用统计学指标快速描述数值型属性的概要

df.describe()

#空值处理

df.fillna(value="NOT PRIDER",inplace=True)

#异常处理

drop_indexs = df.loc[df.["conts_receipt_amt"]<=0]

df.drop[labels=drop_indexs ,axis=0,inplace=True]

parties= {

...}

df["party"] = df["can_nm"].map(parties)

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

df["party"].value_counts()     # 统计列中哥哥元素出现的次数

# 查看各个党派的收到的政治献金总数

df.groupby(by="party")[""contb_receipt_amt].sum()

df.groupby(by=[''dt","party"])[""contb_receipt_amt].sum()

# 将表中日期格式转换为:“yyyy-mm-dd”

def transdate(d):

        day,month,year = d.spllit("-")

        month = months[month]

        return  '20'+year+'-'+str(month)+'-'+day

df["dt"].map(transdate)

# 查看老兵主要支持谁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值