笔记根据B站的波波老师讲课而整理,内容涉及的部分仅仅是Python数据分析的基础
Python数据分析
一、Numpy模块
数组定义操作
基础定义与运算
>>> from numpy import *
>>> a1=array([1,1,1]) #定义一个数组
>>> a2=array([2,2,2])
>>> a1+a2 #对于元素相加
array([3, 3, 3])
>>> a1*2 #乘一个数
array([2, 2, 2])
##
>>> a1=array([1,2,3])
>>> a1
array([1, 2, 3])
>>> a1**2 #表示对数组中的每个数做平方
array([ 1, 8, 27])
##取值,注意的是它是以0为开始坐标,不matlab不同
>>> a1[1]
2
##定义多维数组
>>> a3=array([[1,2,3],[4,5,6]])
>>> a3
array([[1, 2, 3],
[4, 5, 6]])
>>> a3[0] #取出第一行的数据
array([1, 2, 3])
>>> a3[0,0] #第一行第一个数据
1
>>> a3[0][0] #也可用这种方式
1
##数组点乘,相当于matlab点乘操作
>>> a1=array([1,2,3])
>>> a2=array([4,5,6])
>>> a1*a2
array([ 4, 10, 18])
多维数组定义
import numpy as np
a = np.zeros((2,2)) # Create an array of all zeros
print a # Prints "[[ 0. 0.]
# [ 0. 0.]]"
b = np.ones((1,2)) # Create an array of all ones
print b # Prints "[[ 1. 1.]]"
c = np.full((2,2), 7) # Create a constant array
print c # Prints "[[ 7. 7.]
# [ 7. 7.]]"
d = np.eye(2) # Create a 2x2 identity matrix
print d # Prints "[[ 1. 0.]
# [ 0. 1.]]"
e = np.random.random((2,2)) # Create an array filled with random values
print e # Might print "[[ 0.91940167 0.08143941]
# [ 0.68744134 0.87236687]]"
f = np.random.randiant(1, 100, size=(5,6))
#1-100 正数随机出现,size 为 5行6列
切片索引操作
import numpy as np
import matplotlib.pyplot as plt
arr = np.random.randint(1,30, size=(3,4))
arr[1] #取出了numpy数组中的下标为1的行数据
arr[[1,2]] #取出多行数据
#切出arr数组的前两行的数据
arr[0:2]
#切出arr数组的前两列数据
arr[:,0:2] #arr[行切片,列切片]
arr[0:2, 0:2]
#将数组的行倒置
arr[::-1]
#将数组的列倒置
arr[:, ::-1]
#将所有元素倒置
arr[::-1, ::-1]
#----------------------------------------------------------------
#将一张图片进行左右翻转
img_arr = plt.imread('./1.jpg')
img_arr.shape #(766, 640, 3) 三维数组,前两个是像素,第三个数字代表颜色
res = img_arr[:, ::-1,:] #所以只用切列,第一个和第三个都不用改
plt.imshow(res) #pycharm显示不出来。。。。无语子
#图片进行裁剪操作
plt.imshow(img_arr[100:300, 30:190,:]) #进行裁剪
常用数学函数
Numpy自带的数学函数
三角函数 sin() cos() tan()
import numpy as np
arr = np.array([[2,3,4,5,6,1],[4,56,7,88,9,2],[2,3,4,5,6,5]])
sinArr = np.sin(arr) #np.cos(arr) np.tan(arr)
print(sinArr)
#[
# [ 0.90929743 0.14112001 -0.7568025 -0.95892427 -0.2794155 0.84147098]
# [-0.7568025 -0.521551 0.6569866 0.0353983 0.41211849 0.90929743]
# [ 0.90929743 0.14112001 -0.7568025 -0.95892427 -0.2794155 -0.95892427]
#]
这些函数都可以对单独的一个数字进行操作 三角和四舍五入函数
四舍五入函数
np.around(a, decimals=0, out=None)
decimals正数代表小数点后第几位,负数舍入到小数点左侧
import numpy as np
arr = np.array([[2,3,4,5,6,1],[4,56,7,88,9,2],[2,3,4,5,6,5]])
aroundArr = np.around(arr,1)
print(aroundArr)
常用统计函数
-
numpy.amin() 和 numpy.amax() , 用于计算数组中的元素沿指定轴的最小、最大值
-
numpy.ptp() 计算数组中元素最大值与最小值的差
-
numpy.median() 用于计算数组 a 中元素的中位数(中值)
-
标准差std() = sqrt(mean((x - mean())**2))
-
方差var():统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均值
mean((x - mean())**2)
-
统计函数可以使用np自带的函数,也可以使用arr数组中函数
import numpy as np
arr = np.array([[1,2,3,4],[5,6,7,8],[2,3,4,5],[1,9,2,4]])
ptpArr = arr.ptp(axis=0)
stdArr = np.std(arr,axis=0)
varArr = np.std(arr, axis=1)
print(stdArr)
print(varArr)
矩阵操作函数
- Numpy 中包含了一个矩阵库 nump.matlib,该模块中的函数返回的是一个矩阵,而不是ndarray对象。一个矩阵是一个由行(row)列(column)元素排列成的矩阵阵列
- numpy.matlib.identity() 函数返回给定大小的单位矩阵。单位矩阵是个方阵,从左上角到右下角的对角线上的元素均为 1 ,除此以外全都为 0
eyeArr = np.eye(5) #单位矩阵
print(eyeArr)
testArr = np.random.randint(1,19,(3,4))
print(testArr)
print(testArr.T) #转置矩阵
oneArr = np.array([[1,2,3],[2,3,4],[3,4,5]])
twoArr = np.array([[3,4,5],[1,3,2],[2,8,5]])
resArr = np.dot(oneArr,twoArr) #矩阵乘法
print(resArr)
print(oneArr+twoArr) #矩阵加法,直接相加
二、Pandas模块
pandas模块主要处理其他类型(字符串、时间序列),处理非数值型数据
Pandas中两个常用的类 Series DataFrame
Series类
Series是一种类似于一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
Series的创建
- 由列表或ndarray数组创建
- 由字典创建
from pandas import Series
import numpy as np
s = Series(data=[1,2,3,'four'])
print(s)
s = Series(data=np.random.randint(1,19,size=(3,)))
print(s)
#使用索引index增加Series的可读性
s = Series(data=[1,2,3,'four'], index=['a', 'b', 'c', 'd'])
print(s)
dic = {
'语文':100,
'数学':99,
'理综':260
}
s = Series(data=dic)
print(s)
#-------------------------------------------------------------------------------
#索引和切片,因为Series为一维形式,因此和列表差不多
print(s[0])
print(s.语文)
print(s[0:2])
s.shape #形状
s.size #元素个数
s.index #返回索引
s.values #返回所有元素值
s.dtype #返回元素类型
#--------------------------------------------------------------------------------
#常用方法
s.head(3) #显示前n个数据,默认为5个
s.tail(3) #显示后n个数据
s.unique() #对数据进行去重
s.isnull() #用于判断每一个元素是否为空,为空返回True,否则返回false
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
print(s)
'''
a 2.0
b NaN
c 6.0
d NaN
dtype: float64
'''
DataFrame类
创建DataFrame
DataFrame是一个【表格型】的数据结构。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引
- 行索引:index
- 列索引:columns
- 值:values
DataFrame的创建
- ndarray创建
- 字典创建
DataFrame的属性
- values columns index shape dtype(要注意要取出某一列和某一行的数据再进行判断)
DataFrame(data=None, index=None, columns=None, dtype=None) 构造函数
from pandas import DataFrame
import numpy as np
df = DataFrame(data=[[1,2,3],[4,5,6]]) #列表创建
print(df)
df = DataFrame(data=np.random.randint(1,20,size=(5,6))) #ndarray创建
print(df)
dic = {
'name' : ['zhou', 'slis','slgg'],
'salary' : [100, 200, 300]
}
df = DataFrame(data=dic) #字典创建,索引变成了列
print(df)
'''
0 1 2
0 1 2 3
1 4 5 6
0 1 2 3 4 5
0 13 8 9 1 3 7
1 10 1 13 18 8 19
2 13 14 12 7 12 2
3 4 16 13 11 2 12
4 13 5 5 18 3 17
name salary
0 zhou 100
1 slis 200
2 slgg 300
'''
切片和索引
DataFrame类的索引和切片
- 对行进行索引
- 对列进行索引
- 对元素进行索引
from pandas import DataFrame
import numpy as np
df = DataFrame(data=np.random.randint(1,100, size=(8, 4)), index=['1', '2', '3', '4', '5','6','7','8'], columns=['a','b','c','d'])
print(df['a'])
#取单列,如果df有显示的索引,通过索引机制取行或者列的时候只可以使用显示索引print(df[['a', 'c']])
#取多列print(df.iloc[1])
#隐式取行,无论加没加上显示索引,都可以取行print(df.iloc[[0,1,3]])
#取多列
#print(df.loc[2])
#显示取行,此时会报错,如果没有显示的话可以使用这个。有显示的话,只能使用显示print(df.iloc[0,3])
#取单个元素,隐式print(df.loc['1', 'c'])
#显示取元素,如果此时行没有显示,写成了 df.loc[0, 'c']就会报错print(df.iloc[[1,3,4],3])
#取1 3 4 行的 3 列的元素
切片操作:
- 对行切片
- 对列切片
#切片操作-------------------------------------------------------------
print(df['1':'4']) #切行,有显示可以使用,但是隐式一定可以使用
print(df.iloc[:, 0:2]) #切列,iloc一定可以,因为隐式索引一定存在
print(df.loc[:, 'a':'b']) #显示切列
df切片和索引操作
索引:
- df[col] : 取列 (有显示的话,可以使用 df[显示] ,取多个列 df[ [col1, clo2…] ]
- df.iloc[index] : 取行 df.iloc[[index1, index2…]] 取多行
- df.iloc[index,col] :取元素 df.iloc[[1,2,3], 2] 取多个元素
切片:
- df[index1: index4] : 切行,如果有显示的话,可以使用显示1:显示4
- df.iloc[: , col1 : col3] : 切列
类型转换
pd.to_datatime(df[])
df.set_index(keys, inplace = True)
from pandas import DataFrame
import numpy as np
import pandas as pd
#类型转换-----------------------------------------
dic = {
'time' : ['2020-10-10', '2020-11-12', '2018-07-19'],
'timep': [31, 30, 31]
}
df = DataFrame(data=dic)
print(df)
print(df['time'].dtype)
df['time'] = pd.to_datetime(df['time']) #调用pandas模块的to_datatime()方法
print(df['time'].dtype)
df.set_index('time', inplace=True) #加上inplace是原地改变df,否则要赋值给其他
print(df)
'''
time timep
0 2020-10-10 31
1 2020-11-12 30
2 2018-07-19 31
object
datetime64[ns]
timep
time
2020-10-10 31
2020-11-12 30
2018-07-19 31
'''
练习
- 假设dddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与dddd相加,求期中期末成绩平均值
- 假设张三期中考试数学被发现作弊,要记为0分,如何实现?
- 李四因为举报张三作弊立功,期中考试所有科目 成绩加100分,如何实现?
- 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
dic = {
'张三':[150, 150, 150, 150],
'李四':[100, 100, 100,100],
'王五':[140, 145, 148, 149]}
df = DataFrame(data=dic, index=['语文', '数学', '英语', '理综'])mediaTest = dffinalTest = dfmeanScore = (mediaTest + finalTest) / 2
#取平均值
mediaTest.loc['数学','张三'] = 0
#将张三的数学成绩修改为0
mediaTest['李四'] += 100
#李四成绩加100
print(mediaTest)mediaTest += 10
需求:股票分析1
使用tushare包获取某股票的历史行情数据。
输出该股票所有收盘比开盘上涨3%以上的日期。
输出该股票所有开盘比前日收盘跌幅超过29%的日期。
假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易8卖出所有股票,到今天为止,我的收益如何?
#tushare 包,手动下载,财经数据接口包
#使用的时候可以浏览器搜索 tushare,tushare财经数据接口包
import tushare as ts
import pandas as pd
from pandas import DataFrame, Series
import numpy
#获取某只股票的历史行情数据
#df = ts.get_k_data(code='600519', start='2010-01-01')
#print(df)
#df.to_csv('maotai.csv')
#将本地存储的文件读入df中
df = pd.read_csv('maotai.csv')
#删除df中指定一列
df.drop(labels='Unnamed: 0', axis=1, inplace=True) #在drop中 1 代表列
#print(df.info()) #查看每一列的数据类型
#将date列转为时间序列类型
df['date'] = pd.to_datetime(df['date'])
#将date列作为原数据的行索引
df.set_index('date', inplace=True)
#print(df.head())
#找出输出该股票所有收盘比开盘上涨3%以上的日期。
# (收盘 - 开盘) / 开盘 > 0.3
#(df['close'] - df['open']) / df['open'] > 0.03
#在分析过程中如果产生了boolean值则下一步马上将布尔值作为原数据的行索引
#如果布尔值作为行索引,则可以取出TRUE对应的行数据,
#print(df.loc[(df['close'] - df['open']) / df['open'] > 0.03])
#print(df.loc[(df['close'] - df['open']) / df['open'] > 0.03].index)
#输出该股票所有开盘比前日收盘跌幅超过29%的日期。
# (开盘 - 前日收盘) / 前日开盘 将开盘向下移动一个日期
#df['close'] = df['close'].shift(1) #shift(1) 下移一个位置,注意再次赋值为df['close']
#print(df.loc[(df['open'] - df['close']) / df['close'] < -0.02].index)
#假如我从2010年1月1日开始,每月第一个交易日买入1手股票,
# 每年最后一个交易8卖出所有股票,到今天为止,我的收益如何?
#时间节点:2010 - 2020
#一手股票:100支股票
#收益:卖股票挣的钱 - 买股票的钱
# 一个完整的年买入1200支股票,卖出1200支股票
#开盘价
new_df = df['2010-01':'2021-07']
#买入股票,每月的第一个交易日
df_monthly = new_df.resample('M').first()
#数据的重新取样,根据月份从原始数据中提取指定的数据
cost = df_monthly['open'].sum() * 100
#卖出股票到手的钱
#有一种特殊情况:每年最后一年卖出股票,而如今这一年(2021)还没到年底
df_yearly = new_df.resample('A').last()
df_yearly = df_yearly[:-1] #去除最后一行
resv = df_yearly['open'].sum()*1200
#最后手中剩余的股票需要估量其价值计算到总收益中
#使用昨天的收盘价作为剩余股票的单价
last_money = new_df['close'][-1] * 200
#计算总收益
profit = resv + last_money - cost
print(profit)
需求:双均线策略制定
使用tushare包获取某股票的历史行情数据
df = pd.read_csv('./maotai.csv').drop(labels='Unnamed: 0', axis=1)
计算该股票历史数据的5日均线和60日均线
什么是均线?
对于每一个交易日,都可以计算出前N天的移动平均值,然后把这些移动平均值连起来,成为一条线,就叫做N日移动平均线。移动平均线常用线有5天、10天,30天、60天、120天和240天的指标。
5天和10天的是短线操作的参照指标,称做日均线指标:
import pandas as pd
from pandas import DataFrame
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv('./maotai.csv').drop(labels='Unnamed: 0', axis=1)
#将date列转为时间序列,并转为行索引
df['date'] = pd.to_datetime(df['date'])df.set_index('date', inplace = True)
#计算均线,五日均线 30均线
ma5 = df['close'].rolling(5).mean()
ma30=df['close'].rolling(30).mean()
plt.plot(ma5[30:150])
plt.plot(ma30[30:150])
plt.show()
分析输出所有金叉日期和死叉日期
股票分析技术中的金叉和死叉,可以简单解释:
- 分析指标中的两根线,一根为短时间内的指标线,另一根为较长时间的指标线
- 如果短时间的指标线方向拐头向上,并且穿过了较长时间的指标线,这种状态叫 ”金叉“
- 如果短时间的指标线方向拐头向下,并且穿过了较长时间的指标线,这种状态叫 ”死叉“
- 一般情况下,出现金叉后,操作趋向买入;死叉则趋向卖出。当然,金叉和死叉只是分析指标之一,要和其他很多指标配合使用,才能增加操作的准确性。
#金叉与死叉的查找
ma5 = ma5[30:] #去除为空值的部分
ma30 = ma30[30:]
s1 = ma5 < ma30 #两个判断条件,返回的是 布尔值s2 = ma5 > ma30
df = df[30:] #为了适应 ma5和ma30的切割,所以也要切片
death_ex = s1 & s2.shift(1) #s2下移一个,然后与s1进行 与 运算
death_date = df.loc[death_ex].index
print(death_date)
golden_ex = -(s1 | s2.shift(1))
#判定金叉时间
golden_date = df.loc[golden_ex].index
print(golden_date)
如果我从2010年1月1 日开始,初始资金为100000元,金叉尽量买入,死叉全部卖出,则到今天为止,我的炒股收益如何?
'''买卖股票的单价使用开盘价买卖股票的时机最终手里会有股票没有卖出
去 会有。如果最后一天为金叉,则买入股票(卖不出去了)。估量剩余
股票的价值计算到总收益。 剩余股票的单价就是用最后一天的收盘
价。 金叉和死叉是交替出现的吗,还是说会出现连续都是金叉的现
象?'''
s3 = Series(data=1, index=golden_date) # 1 作为金叉的标识
s4 = Series(data=0, index=death_date) # 0 作为死叉的标识
s = s3.append(s4)
s = s.sort_index() #排序之后,1和0交叉排序,存储的是金叉和死叉的时间
s = s['2010':'2020']
#print(s)
first_money = 100000 #本金,不变
money = first_money #可变的,买股票的钱和卖出股票收益的钱都从该变量中操作
hold_all = 0
#持有股票的数量 100股 = 1手,一开始我以为可以有连续金叉,这样就需要hold_all
#金叉和死叉好像是交替出现的
for i in range(len(s)): # s[i] = 0 or s[i] = 1
if s[i] == 1: #金叉时间,买入股票
#获取股票的单价,(金叉时间对应的行数据中的开盘价)
time = s.index[i] # 取出对应的索引
p = df.loc[time]['open'] #股票单价,当天的开盘价
hand_count = money // (p * 100)
#使用money最多可以买入多少支股票
hold = hand_count * 100
hold_all += hold
money -= (hold * p) #将买股票的钱从本金中减去
else: # 将买入的股票卖出去
death_time = s.index[i] # 取出对应的索引,死叉时间
p = df.loc[death_time]['open'] # 股票单价,当天的开盘价
money += p * hold_all
hold_all = 0
last_money = hold_all * df['close'][-1]
res = money + last_money - first_money
print(res)
三、数据清洗
-
原始数据中会存在缺失值(空值)
-
重复值
-
异常值
缺失值的清洗
有两种丢失数据:
- None
- np.nan(NaN)
两种数据类型的区别:
type(None) #就是 None类型
type(np.nan) #float类型
为什么需要 np.nan类型,因为 np.nan + 1 = np.nan ,空值参加运算之后还是空值。
而None类型参与运算会报错
在pandas中,None类型会自动被转换为 NaN 类型
import pandas as pd
import numpy as np
from pandas import DataFrame, Series
#伪造一组数据值
df = DataFrame(data=np.random.randint(1, 100, size=(8,7)))
df.iloc[2,3] = None
df.iloc[4,4] = np.nan
df.iloc[5,2] = None
#方式一:对空值进行过滤(删除空值所在行) isnull - any notnull - all
df.isnull().any(axis=1) #any用来检测行或者列中是否存在 True
#将上述的布尔值作为源数据的行索引
df.loc[df.isnull().any(axis=1)].index
#获取这些索引
drop_index = df.loc[df.isnull().any(axis=1)].index
df.drop(labels=drop_index, axis=0) #对缺失行进行删除
#或者使用 notnull()
df.loc[df.notnull().all(axis=1)].index
#或者直接使用 dropna()方法进行删除,可以删除行或者列
df.dropna(axis=0) #删除行
#方式二:对空值进行赋值,临近的值 fillna(value=?) 或者 method参数
df.fillna(value=666)
df.fillna(method='ffill', axis=1) #使用水平向前的值去填充
df.fillna(method='bfill', axis=1) #使用水平向后的值去填充
重复值清洗
#生成一组带有重复值的数据
import numpy as np
import pandas as pd
from pandas import DataFrame, Series
df = DataFrame(data=np.random.randint(1, 100, size=(8, 4)))
df.iloc[2] = [0, 0, 0, 0]
df.iloc[3] = [0,0,0,0]
df.iloc[5] = [0,0,0,0]
df.drop_duplicates(keep="first")
#使用drop_duplicates()方法,默认保留第一个出现的重复值
异常值清洗
自定义一个100行3列 (A, B, C)取值范围为0-1的数据源,然后将C列中的值大于其两倍标准差的异常值进行数据清洗
df = DataFrame(data=np.random.random(size=(100, 3)), columns=['A', 'B', 'C'])
#判定异常值的条件
twice_std = df['C'].std() * 2
df['C'] > twice_std
df.loc[-(df['C'] > twice_std)]
四、Pandas高级
DataFrame级联
匹配级联
import numpy as np
import pandas as pd
from pandas import DataFrame, Series
#匹配级联
df1 = DataFrame(data=np.random.randint(1, 100, size=(5, 3)), columns=['A', 'B', 'C'])
df2 = DataFrame(data=np.random.randint(1, 100, size=(5, 3)), columns=['A', 'D', 'C'])
df3 = pd.concat((df1, df2), axis=1) #行级联
#print(df3)
不匹配级联
不匹配级联指的是级联的维度的索引不一致,例如纵向级联时索引不一致,横向级联时行索引不一致
有2种连接方式:
- 外连接:补NAN
- 内连接:只连接匹配的项
如果想要保留数据的完整性,必须使用outer(外连接)
append函数的使用,也是外连接
df4 = pd.concat((df1, df2), axis=0) #列级联,外连接
print(df4)
'''
A B C D
0 91 53.0 81 NaN
1 5 60.0 10 NaN
2 97 72.0 32 NaN
3 83 88.0 55 NaN
4 27 84.0 38 NaN
0 2 NaN 81 30.0
1 48 NaN 92 81.0
2 55 NaN 59 96.0
3 95 NaN 24 26.0
4 8 NaN 58 55.0
'''
pd.concat((df1, df2), axis=0, join='inner') #内连接
'''
A C
0 84 93
1 80 41
2 51 6
3 79 17
4 81 54
0 24 24
1 20 23
2 92 35
3 70 85
4 97 4
'''
DataFrame合并
合并操作
- merge与concat的区别在于,merge需要依据某一共同列来进行合并
- 使用pd.merge()合并时,会自动根据两者相同columu名称的那一列,作为key来进行合并。
- 注意每一列元素的顺序不要求一致
#合并操作-------------------------------------------------
df1 = DataFrame(data={'employee':['tom', 'javk', 'widk'],
'work':['com', 'sice', 'teach']})
df2 = DataFrame(data={'employee':['javk', 'widk', 'tom'],
'group':['ali', 'tencet', 'baidu']})
pd.merge(df1, df2, how='outer') #outer inner left right
Pandas替换
替换操作:
替换操作可以同步作用于Series和DataFrame中
单值替换
- 普通替换:替换所有符合要求的元素:to_replace = 15, value=‘e’
- 按列指定单值替换:to_replace={列标签:替换值} value=‘value’
多值替换
- 列表替换:to_replace=[] value = []
- 字典替换:(推荐)to_replace={to_replace:value, to_replace:value}
df = DataFrame(data=np.random.randint(1,100, size=(5,4)))
df.replace(to_replace=2, value='Two')
df.replace(to_replace={1:'one'}) #多值替换
#将指定列的值进行替换
df.replace(to_replace={4:5}, value='five')
Pandas映射
映射
- 概念:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定(给一个元素提供不同的表现形式)
- 创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名
dic = {
'name':['张三','李四','张三'],
'salary':[15000, 20000, 15000]
}
df = DataFrame(date=dic)
#映射关系表
dic2 = {
'张三':'tom',
'李四':'jack'
}
df['name'].map(dic2) #map()函数只有Series可以,df['name']一列就是Series
运算工具
超过3000部分的钱缴纳5%的税,计算个人的税后缴费
#自定义一个函数,作为计算法则
def after_sal(s):
return s if s <= 3000 else s - (s - 3000) * 0.05
df['after_sal'] = df['salary'].map(after_sal)
排序实现的随机抽样
- take()
- np.random.permutation()
df = DataFrame(data=np.random.randint(1,100, size=(100,3)), columns=['A', 'B', 'C'])
#将原始数据打乱
df.take([2, 0, 1], axis=1) #axis和drop一样,1为列
#生成乱序的随机序列
np.random.permutation(10)
#行和列都被随机打乱了
df.take(np.random.permutation(3), axis=1).take(np.random.permutation(100), axis=0)
df.take(np.random.permutation(3), axis=1).take(np.random.permutation(100), axis=0)[0:50] #随机进行取样
Pandas分组聚合
数据的分类处理
数据分类处理的核心
groupby()函数
groups属性查看分组情况
import pandas as pd
from pandas import DataFrame
import numpy as np
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= DataFrame(data=dic)
#想要水果的种类进行分析
df.groupby(by='item').groups
#分组聚合,计算出每一种水果的平均价格
df.groupby(by='item')['price'].mean()
#计算每一种颜色对应水果的平均重量
df.groupby(by='color')['weight'].mean()