机器学习(常用科学计算库)
前言:由于 python 数据分析非常重要,有小伙伴私信我能不能梳理之前文科转码时快速学习数据分析基础的方法,今天下班后花了很多时间重新梳理了一下机器学习基础之(常用科学计算库),能够解决大多数工作上的自动化计算任务!希望对各位小伙伴有帮助!
文章目录
一、Numpy
1. Numpy的优势
(1)内存块风格
ndarray中所有元素的类型一致,内存可以连续,节省很多循环语句。(相较于python中 list
)
(2)并行化(向量化)计算
(3)效率高于纯python
Numpy底层是c语言,内部解除了GIL(全局解释器锁)。
2. N维数组-ndarray
(1) 常用属性
属性名字 | 属性解释 |
---|---|
ndarray.shape | 数组维度的元组 |
ndarray.ndim | 数组维数 |
ndarray.size | 数组中的元素数量 |
ndarray.itemsize | 一个数组元素的长度(字节) |
ndarray.dtype | 数组元素的类型 |
(2) 数据类型
若不指定,整数默认是int32,浮点数默认是float64
3. Numpy基本操作
(1) 生成0和1数组
- np.ones(shape, dtype)
- np.ones_like(a, dtype)
- np.zeros(shape, dtype)
- np.zeros_like(a, dtype)
(2) 深拷贝和浅拷贝
- np.array(object, dtype) —— 深拷贝
- np.asarray(a, dtype) —— 浅拷贝
(3) 切片范围生成
- 1-np.linspace (start, stop, num, endpoint)
- 创建等差数组 — 指定数量
- 参数:
- start:序列的起始值
- stop:序列的终止值
- num:要生成的等间隔样例数量,默认为50
- endpoint:序列中是否包含stop值,默认为ture
# 生成等间隔的数组
np.linspace(0, 100, 11)
array([ 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.])
- 2-np.arange(start,stop, step, dtype)
- 创建等差数组 — 指定步长
- 参数
- step:步长,默认值为1
np.arange(10, 50, 2)
array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
44, 46, 48])
- 3-np.logspace(start,stop, num)
- 创建等比数列
- 参数:
- num:要生成的等比数列数量,默认为50
# 生成10^x
np.logspace(0, 2, 3)
array([ 1., 10., 100.])
(4) 生成随机数组
- 1-正态分布:np.random.normal(*loc=0.0*, *scale=1.0*, *size=None*)
举例1:生成均值为1.75,标准差为1的正态分布数据,100000000个
x1 = np.random.normal(1.75, 1, 100000000)
array([2.90646763, 1.46737886, 2.21799024, ...,
1.56047411, 1.87969135,0.9028096 ])
举例2:随机生成4支股票1周的交易日涨幅数据
4支股票,一周(5天)的涨跌幅数据,如何获取?
随机生成涨跌幅在某个正态分布内,比如均值0,方差1
股票涨跌幅数据的创建
# 创建符合正态分布的4只股票5天的涨跌幅数据
stock_change = np.random.normal(0, 1, (4, 5))
stock_change
array([[ 0.0476585 , 0.32421568, 1.50062162, 0.48230497, -0.59998822],
[-1.92160851, 2.20430374, -0.56996263, -1.44236548, 0.0165062 ],
[-0.55710486, -0.18726488, -0.39972172, 0.08580347, -1.82842225],
[-1.22384505, -0.33199305, 0.23308845, -1.20473702, -0.31753223]])
- 2-均匀分布:np.random.uniform(*low=0.0*, *high=1.0*, *size=None*)
# 生成均匀分布的随机数(左闭右开)
x2 = np.random.uniform(-1, 1, 100000000)
array([ 0.22411206, 0.31414671, 0.85655613, ..., -0.92972446,
0.95985223, 0.23197723])
- 3-随机整数 :np.random.randint(low, high=None, size=None, dtype=‘l’)
import numpy as np
# 生成 3 个 随机整数,范围是 0 到 999
random_unique = np.random.randint(0, 1000, size=3)
print(random_unique)
- 4-随机整数:np.random.choice()
import numpy as np
# 生成 3 个不重复的随机整数,范围是 0 到 999
random_unique = np.random.choice(1000, size=3, replace=False)
print(random_unique)
(5) 修改形状
- 1-ndarray.reshape(shape, order)
# 在转换形状的时候,一定要注意数组的元素匹配
stock_change.reshape([5, 4])
stock_change.reshape([-1,10]) # 数组的形状被修改为: (2, 10), -1: 表示通过待计算
- 2-ndarray.resize(new_shape)
stock_change.resize([5, 4])
# 查看修改后结果
stock_change.shape
(5, 4)
- 3-转置ndarray.T
stock_change.T.shape
(4, 5)
(6)修改类型
- 1-ndarray.astype(type)
stock_change.astype(np.int32)
- 2-ndarray.tostring([order])或者ndarray.tobytes([order])
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
arr.tostring()
(7) 去重
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
>>> np.unique(temp)
array([1, 2, 3, 4, 5, 6])
4. ndarray运算
(1) 逻辑运算
# 生成10名同学,5门功课的数据
>>> score = np.random.randint(40, 100, (10, 5))
# 取出最后4名同学的成绩,用于逻辑判断
>>> test_score = score[6:, 0:5]
# 逻辑判断, 如果成绩大于60就标记为True 否则为False
>>> test_score > 60
array([[ True, True, True, False, True],
[ True, True, True, False, True],
[ True, True, False, False, True],
[False, True, True, True, True]])
# BOOL赋值, 将满足条件的设置为指定的值-布尔索引
>>> test_score[test_score > 60] = 1
>>> test_score
array([[ 1, 1, 1, 52, 1],
[ 1, 1, 1, 59, 1],
[ 1, 1, 44, 44, 1],
[59, 1, 1, 1, 1]])
(2) 判断函数
- 1-np.all()
# 判断前两名同学的成绩[0:2, :]是否全及格
>>> np.all(score[0:2, :] > 60)
False
- 2-np.any()
# 判断前两名同学的成绩[0:2, :]是否有大于90分的
>>> np.any(score[0:2, :] > 80)
True
(3) 三元运算符
- 1-np.where()
# 判断前四名学生,前四门课程中,成绩中大于60的置为1,否则为0
temp = score[:4, :4]
np.where(temp > 60, 1, 0)
- 2-复合逻辑需要结合np.logical_and和np.logical_or使用
# 判断前四名学生,前四门课程中,成绩中大于60且小于90的换为1,否则为0
np.where(np.logical_and(temp > 60, temp < 90), 1, 0)
# 判断前四名学生,前四门课程中,成绩中大于90或小于60的换为1,否则为0
np.where(np.logical_or(temp > 90, temp < 60), 1, 0)
(4) 统计运算
- min(a, axis)——最小值
- Return the minimum of an array or minimum along an axis.
- max(a, axis])——最大值
- Return the maximum of an array or maximum along an axis.
- median(a, axis)——中位数
- Compute the median along the specified axis.
- mean(a, axis, dtype)——平均数
- Compute the arithmetic mean along the specified axis.
- std(a, axis, dtype)——标准差
- Compute the standard deviation along the specified axis.
- var(a, axis, dtype)——方差
- Compute the variance along the specified axis.
进行统计的时候,axis 轴的取值并不一定,Numpy中不同的API轴的值都不一样,在这里,axis 0代表列, axis 1代表行去进行统计
# 接下来对于前四名学生,进行一些统计运算
# 指定列 去统计
temp = score[:4, 0:5]
print("前四名学生,各科成绩的最大分:{}".format(np.max(temp, axis=0)))
print("前四名学生,各科成绩的最小分:{}".format(np.min(temp, axis=0)))
print("前四名学生,各科成绩波动情况:{}".format(np.std(temp, axis=0)))
print("前四名学生,各科成绩的平均分:{}".format(np.mean(temp, axis=0)))
前四名学生,各科成绩的最大分:[96 97 72 98 89]
前四名学生,各科成绩的最小分:[55 57 45 76 77]
前四名学生,各科成绩波动情况:[16.25576821 14.92271758 10.40432602 8.0311892 4.32290412]
前四名学生,各科成绩的平均分:[78.5 75.75 62.5 85. 82.25]
如果需要统计出某科最高分对应的是哪个同学?
np.argmax(temp, axis=)
np.argmin(temp, axis=)
print("前四名学生,各科成绩最高分对应的学生下标:{}".format(np.argmax(temp, axis=0)))
前四名学生,各科成绩最高分对应的学生下标:[0 2 0 0 1]
5. 数组间运算
- 广播机制
广播机制需要扩展维度小的数组,使得它与维度最大的数组的shape值相同,以便使用元素级函数或者运算符进行运算。
6. 矩阵乘法
- np.matmul
- np.dot
案例: 期末成绩0.7,平时成绩0.3
>>> a = np.array([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
>>> b = np.array([[0.7], [0.3]])
>>> np.matmul(a, b)
array([[81.8],
[81.4],
[82.9],
[90. ],
[84.8],
[84.4],
[78.6],
[92.6]])
>>> np.dot(a,b)
array([[81.8],
[81.4],
[82.9],
[90. ],
[84.8],
[84.4],
[78.6],
[92.6]])
np.matmul和np.dot的区别:
二者都是矩阵乘法。 np.matmul中禁止矩阵与标量的乘法。 在矢量乘矢量的內积运算中,np.matmul与np.dot没有区别。
二、 Pandas
1. pandas 三种数据结构
Pandas中一共有三种数据结构,分别为:Series、DataFrame和MultiIndex(老版本中叫Panel )。
其中Series是一维数据结构,DataFrame是二维的表格型数据结构,MultiIndex是三维的数据结构。
(1) series
Series类似一维数组,能够保存任何类型数据,比如整数、字符串、浮点数等,主要由一组数据和与之相关的索引两部分构成。
-
1-series的创建
pd.Series(data=None, index=None, dtype=None)
-
A-指定索引
pd.Series([6.7,5.6,3,10,2], index=[1,2,3,4,5]) # 运行结果 1 6.7 2 5.6 3 3.0 4 10.0 5 2.0 dtype: float64
-
B-字典创建
color_count = pd.Series({'red':100, 'blue':200, 'green': 500, 'yellow':1000}) color_count # 运行结果 blue 200 green 500 red 100 yellow 1000 dtype: int64
-
C-指定内容,默认索引
pd.Series(np.arange(10)) # 运行结果 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 dtype: int64
-
-
2-series的属性
-
A-index
color_count.index # 结果 Index(['blue', 'green', 'red', 'yellow'], dtype='object')
-
B-values
color_count.values # 结果 array([ 200, 500, 100, 1000])
-
C-索引获取数据
color_count[2] # 结果 100
-
(2) dataframe
DataFrame是一个类似于二维数组或表格(如excel)的对象,既有行索引,又有列索引
- 行索引,表明不同行,横向索引,叫index,0轴,axis=0
- 列索引,表名不同列,纵向索引,叫columns,1轴,axis=1
-
1-DataFrame的创建
# 导入pandas import pandas as pd pd.DataFrame(data=None, index=None, columns=None)
# 构造行索引序列 subjects = ["语文", "数学", "英语", "政治", "体育"] # 构造列索引序列 stu = ['同学' + str(i) for i in range(score_df.shape[0])] # 添加行索引 data = pd.DataFrame(score, columns=subjects, index=stu)
-
2-Dataframe的属性
-
A-shape
data.shape # 结果 (10, 5)
-
B-index
data.index # 结果 Index(['同学0', '同学1', '同学2', '同学3', '同学4', '同学5', '同学6', '同学7', '同学8', '同学9'], dtype='object')
-
C-columns
data.columns # 结果 Index(['语文', '数学', '英语', '政治', '体育'], dtype='object')
-
D-values
data.values array([[92, 55, 78, 50, 50], [71, 76, 50, 48, 96], [45, 84, 78, 51, 68], [81, 91, 56, 54, 76], [86, 66, 77, 67, 95], [46, 86, 56, 61, 99], [46, 95, 44, 46, 56], [80, 50, 45, 65, 57], [41, 93, 90, 41, 97], [65, 83, 57, 57, 40]])
-
E-转置
data.T
-
F-head()
-
G-tail()
-
-
3-DataFrame索引的设置
-
A-修改行索引
stu = ["学生_" + str(i) for i in range(score_df.shape[0])] # 必须整体全部修改 data.index = stu
-
B-重设索引
reset_index(drop=False) 设置新的下标索引 drop:默认为False,不删除原来索引,如果为True,删除原来的索引值
-
C-以某列值设置为新的索引
set_index(keys, drop=True) keys : 列索引名成或者列索引名称的列表 drop : boolean, default True.当做新的索引,删除原来的列 df.set_index('month') # 设置多重索引 df = df.set_index(['year', 'month'])
-
(3) MultiIndex与Panel
- 1-MultiIndex
MultiIndex是三维的数据结构
df.index
MultiIndex(levels=[[2012, 2013, 2014], [1, 4, 7, 10]],
labels=[[0, 2, 1, 2], [0, 1, 2, 3]],
names=['year', 'month'])
属性:
df.index.names
# FrozenList(['year', 'month'])
df.index.levels
# FrozenList([[2012, 2013, 2014], [1, 4, 7, 10]])
multiIndex的创建:
arrays = [[1, 1, 2, 2], ['red', 'blue', 'red', 'blue']]
pd.MultiIndex.from_arrays(arrays, names=('number', 'color'))
# 结果
MultiIndex(levels=[[1, 2], ['blue', 'red']],
codes=[[0, 0, 1, 1], [1, 0, 1, 0]],
names=['number', 'color'])
- 2-Panel
pandas.Panel
(data=None, items=None, major_axis=None, minor_axis=None)
- 作用:存储3维数组的Panel结构
- 参数:
- data : ndarray或者dataframe
- items : 索引或类似数组的对象,axis=0
- major_axis : 索引或类似数组的对象,axis=1
- minor_axis : 索引或类似数组的对象,axis=2
p = pd.Panel(data=np.arange(24).reshape(4,3,2),
items=list('ABCD'),
major_axis=pd.date_range('20130101', periods=3),
minor_axis=['first', 'second'])
# 结果
<class 'pandas.core.panel.Panel'>
Dimensions: 4 (items) x 3 (major_axis) x 2 (minor_axis)
Items axis: A to D
Major_axis axis: 2013-01-01 00:00:00 to 2013-01-03 00:00:00
Minor_axis axis: first to second
查看panel数据:
p[:,:,"first"]
p["B",:,:]
注:Pandas从版本0.20.0开始弃用:推荐的用于表示3D数据的方法是通过DataFrame上的MultiIndex方法
2. 基本操作
(1) 直接使用行列索引(先列后行)
# 直接使用行列索引名字的方式(先列后行)
data['open']['2018-02-27']
23.53
(2) 结合loc或者iloc使用索引
获取从'2018-02-27':'2018-02-22','open'的结果
# 使用loc:只能指定行列索引的名字
data.loc['2018-02-27':'2018-02-22', 'open']
2018-02-27 23.53
2018-02-26 22.80
2018-02-23 22.88
Name: open, dtype: float64
# 使用iloc可以通过索引的下标去获取
# 获取前3天数据,前5列的结果
data.iloc[:3, :5]
open high close low
2018-02-27 23.53 25.88 24.16 23.53
2018-02-26 22.80 23.78 23.53 22.80
2018-02-23 22.88 23.37 22.82 22.71
(3) 使用ix组合索引
获取行第1天到第4天,['open', 'close', 'high', 'low']这个四个指标的结果
# 使用ix进行下表和名称组合做引
data.ix[0:4, ['open', 'close', 'high', 'low']]
# 推荐使用loc和iloc来获取的方式
data.loc[data.index[0:4], ['open', 'close', 'high', 'low']]
data.iloc[0:4, data.columns.get_indexer(['open', 'close', 'high', 'low'])]
open close high low
2018-02-27 23.53 24.16 25.88 23.53
2018-02-26 22.80 23.53 23.78 22.80
2018-02-23 22.88 22.82 23.37 22.71
2018-02-22 22.25 22.28 22.76 22.02
(4) 赋值操作
对DataFrame当中的close列进行重新赋值为1
# 直接修改原来的值
data['close'] = 1
# 或者
data.close = 1
(5) 排序
- 1-dataframe排序
# 按照开盘价大小进行排序 , 使用ascending指定按照大小排序,True升序
data.sort_values(by="open", ascending=True).head()
# 按照多个键进行排序
data.sort_values(by=['open', 'high'])
# 对索引进行排序,升序
data.sort_index()
- series排序(只有一列)
data['p_change'].sort_values(ascending=True).head()
2015-09-01 -10.03
2015-09-14 -10.02
2016-01-11 -10.02
2015-07-15 -10.02
2015-08-26 -10.01
Name: p_change, dtype: float64
使用series.sort_index()进行排序,与df一致
3. dataframe的运算
(1) 算术运算
加法:add(other)
比如进行数学运算加上具体的一个数字
data['open'].add(1)
2018-02-27 24.53
2018-02-26 23.80
2018-02-23 23.88
2018-02-22 23.25
2018-02-14 22.49
减法:sub(other)
(2) 逻辑运算
- 1-逻辑运算符号
# 逻辑判断的结果可以作为筛选的依据
data[data["open"] > 23].head()
data[(data["open"] > 23) & (data["open"] < 24)].head()
- 2-逻辑运算函数
data.query("open<24 & open>23").head()
# 可以指定值进行一个判断,从而进行筛选操作
data[data["open"].isin([23.53, 23.85])]
(3) 统计运算
综合分析:
# 计算平均值、标准差、最大值、最小值
data.describe()
count | Number of non-NA observations |
---|---|
sum | Sum of values |
mean | Mean of values |
median | Arithmetic median of values |
min | Minimum |
max | Maximum |
mode | Mode |
abs | Absolute Value |
prod | Product of values |
std | Bessel-corrected sample standard deviation |
var | Unbiased variance |
idxmax | compute the index labels with the maximum |
idxmin | compute the index labels with the minimum |
累计统计函数
函数 | 作用 |
---|---|
cumsum | 计算前1/2/3/…/n个数的和 |
cummax | 计算前1/2/3/…/n个数的最大值 |
cummin | 计算前1/2/3/…/n个数的最小值 |
cumprod | 计算前1/2/3/…/n个数的积 |
排序
# 排序之后,进行累计求和
data = data.sort_index()
stock_rise = data['p_change']
# plot方法集成了前面直方图、条形图、饼图、折线图
stock_rise.cumsum()
2015-03-02 2.62
2015-03-03 4.06
2015-03-04 5.63
2015-03-05 7.65
2015-03-06 16.16
2015-03-09 16.37
2015-03-10 18.75
2015-03-11 16.36
2015-03-12 15.03
2015-03-13 17.58
2015-03-16 20.34
2015-03-17 22.42
2015-03-18 23.28
2015-03-19 23.74
2015-03-20 23.48
2015-03-23 23.74
(4) 自定义运算
apply(func, axis=0)
func:自定义函数
axis=0:默认是列,axis=1为行进行运算
定义一个对列,最大值-最小值的函数
data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)
open 22.74
close 22.85
dtype: float64
4. 文件读取与存储
(1) read_csv()
- pandas.read_csv(filepath_or_buffer, sep =‘,’, usecols )
- filepath_or_buffer:文件路径
- sep :分隔符,默认用","隔开
- usecols:指定读取的列名,列表形式
# 读取文件,并且指定只获取'open', 'close'指标
data = pd.read_csv("./data/stock_day.csv", usecols=['open', 'close'])
open close
2018-02-27 23.53 24.16
2018-02-26 22.80 23.53
2018-02-23 22.88 22.82
2018-02-22 22.25 22.28
2018-02-14 21.49 21.92
(2) to_csv()
- DataFrame.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode=‘w’, encoding=None)
- path_or_buf :文件路径
- sep :分隔符,默认用","隔开
- columns :选择需要的列索引
- header :boolean or list of string, default True,是否写进列索引值
- index:是否写进行索引
- mode:‘w’:重写, ‘a’ 追加
# 选取10行数据保存,便于观察数据
data[:10].to_csv("./data/test.csv", columns=['open'])
# index:存储不会讲索引值变成一列数据
data[:10].to_csv("./data/test.csv", columns=['open'], index=False)
(3) read_hdf与to_hdf
pip install tables
day_close.to_hdf("./data/test.h5", key="day_close")
new_close = pd.read_hdf("./data/test.h5", key="day_close")
注意:优先选择使用HDF5文件存储
- HDF5在存储的时候支持压缩,使用的方式是blosc,这个是速度最快的也是pandas默认支持的
- 使用压缩可以提磁盘利用率,节省空间
- HDF5还是跨平台的,可以轻松迁移到hadoop 上面
(4) json
json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
orient="records"
: 这个参数指定了JSON数据的格式。"records"
表示JSON数据是一个数组,每个元素都是一个记录(行),具有相同的结构。lines=True
: 这个参数指示JSON数据应该被视为多行格式。多行格式的JSON数据是一个数组,其中每个元素都是一个单独的JSON对象,而不是嵌套的对象或数组。
json_read.to_json("./data/test.json", orient='records', lines=True)
5. 处理缺失值
- 目标
- 应用isnull判断是否有缺失数据NaN
- 应用fillna实现缺失值的填充
- 应用dropna实现缺失值的删除
- 应用replace实现数据的替换
(1) 判断缺失值是否存在
pd.notnull()
pd.isnull()
np.all(pd.notnull(movie))
(2) 存在缺失值nan,并且是np.nan
- 1-删除
# 不修改原数据
movie.dropna()
# 可以定义新的变量接受或者用原来的变量名
data = movie.dropna()
- 2-替换
# 替换存在缺失值的样本的两列
# 替换填充平均值,中位数
# movie['Revenue (Millions)'].fillna(movie['Revenue (Millions)'].mean(), inplace=True)
替换所有缺失值:
for i in movie.columns:
if np.all(pd.notnull(movie[i])) == False:
print(i)
movie[i].fillna(movie[i].mean(), inplace=True)
(3) 不是缺失值nan,有默认标记的
# 全局取消证书验证
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# 把一些其它值标记的缺失值,替换成np.nan
wis = wis.replace(to_replace='?', value=np.nan)
# 删除
wis = wis.dropna()
6. 数据离散化
使用的工具:
- pd.qcut(data, q):
- 对数据进行分组将数据分组,一般会与value_counts搭配使用,统计每组的个数
- series.value_counts():统计分组次数
# 自行分组
qcut = pd.qcut(p_change, 10)
# 计算分到每个组数据个数
qcut.value_counts()
自定义区间分组:
- pd.cut(data, bins)
# 自己指定分组区间
bins = [-100, -7, -5, -3, 0, 3, 5, 7, 100]
p_counts = pd.cut(p_change, bins)
- 什么是one-hot编码
把每个类别生成一个布尔列,这些列中只有一列可以为这个样本取值为1.其又被称为热编码。
- pandas.get_dummies(data, prefix=None)
- data:array-like, Series, or DataFrame
- prefix:分组名字
# 得出one-hot编码矩阵
dummies = pd.get_dummies(p_counts, prefix="rise")
7. 数据合并
(1) pd.concat()
pd.concat([data1, data2], axis=1)
按照行或列进行合并,axis=0为列索引,axis=1为行索引
(2) pd.merge()
- pd.merge(left, right, how=‘inner’, on=None)
- 可以指定按照两组数据的共同键值对合并或者左右各自
left
: DataFrameright
: 另一个DataFrameon
: 指定的共同键- how:按照什么方式连接
8. 交叉表和透视表
(1) 交叉表
# 寻找星期几跟股票张得的关系
# 1、先把对应的日期找到星期几
date = pd.to_datetime(data.index).weekday
data['week'] = date
# 2、假如把p_change按照大小去分个类0为界限
data['posi_neg'] = np.where(data['p_change'] > 0, 1, 0)
# 通过交叉表找寻两列数据的关系
count = pd.crosstab(data['week'], data['posi_neg'])
# 算数运算,先求和
sum = count.sum(axis=1).astype(np.float32)
# 进行相除操作,得出比例
pro = count.div(sum, axis=0)
pro.plot(kind='bar', stacked=True)
plt.show()
(2) 透视表
# 通过透视表,将整个过程变成更简单一些
data.pivot_table(['posi_neg'], index='week')
9. 分组和聚合
(1) 分组
- DataFrame.groupby(key, as_index=False)
- key:分组的列数据,可以多个
# 分组,求平均值
col.groupby(['color'])['price1'].mean()
col['price1'].groupby(col['color']).mean()
color
green 2.025
red 2.380
white 5.560
Name: price1, dtype: float64
# 分组,数据的结构不变
col.groupby(['color'], as_index=False)['price1'].mean()
color price1
0 green 2.025
1 red 2.380
2 white 5.560