NumPy
NumPy擅长矩阵的计算,是数据分析中常用的工具。
1. 安装类库
pip install NumPy
2. 创建矩阵
import numpy as np
# list
jeff_salary = [2700,3000,3000]
nick_salary = [2600,2800,2800]
tom_salary = [2300,2500,2500]
# 使用list构建矩阵
base_salary = np.array([jeff_salary, nick_salary, tom_salary])
# 打印矩阵
print(base_salary)
通过import numpy as np导入类库
numpy.array([alist, blist, clist])构建矩阵
jeff_bonus = [500,400,400]
nick_bonus = [600,300,400]
tom_bonus = [200,500,400]
# 这是一个二维数组,第0维是竖向,第1维是横向
bonus = np.array([jeff_bonus, nick_bonus, tom_bonus])
3. 元素计算
# 逐个对应位置的元素相加
salary_bonus = base_salary + bonus
print(type(salary_bonus))
print(salary_bonus)
元素计算是对两个同维矩阵的计算,对逐个位置的元素进行合并计算。
4. 查找元素中的最值
# 打印元素中的最大值
print(salary_bonus.max())
结果为3400,这是所有元素中最大的那个值
5. 找到某个维度上的最大值
使用amax可以获取某个维度的最值,axis=1表示横向,axis=0表示纵向
每行的最大值:
print(np.amax(salary_bonus, axis = 1))
[3400, 3200, 3000]
每列的最大值:
print(np.amax(salary_bonus, axis = 0))
[3200, 3400, 3400]
其他资料https://NumPy.org/doc/stable/reference/routines.statistics.html
pandas
1. 安装类库
pip install pandas
2. 创建Series
我们经常使用的是DataFrame数据结构,也就是矩阵,实际上,矩阵是由Series组成的,单个列向量就是Series
通过pandas.Series(list)即可根据一个List创建一个 Series,我们习惯上Series内数据类型一致:
import pandas as pd
# list
data = ['Jeff Russell','Jane Boorman','Tom Heints']
# 转Series
s = pd.Series(data)
# 打印
print(s)
打印结果会发现,Series带有标签,默认是从0开始的索引
3. 指定索引
我们也可以在创建Series的时候,指定索引,而不是默认从0开始
import pandas as pd
data = ['Jeff Russell','Jane Boorman','Tom Heints']
# 通过index参数指定了索引
emps_names = pd.Series(data, index=[9001,9002,9003])
print(emps_names)
打印结果中的索引按照我们的预期进行着:
4. 数据的获取
直接通过索引获取,按照我们指定的索引进行
print(emps_names[9001])
等价于使用loc属性进行访问
print(emps_names.loc[9001])
也可以使用位置,而不是索引, 使用iloc
print(emps_names.iloc[0])
也可以使用切片,访问某个范围
print(emps_names.loc[9001:9002])
或者
print(emps_names.iloc[0:2])
注意,此处的使用,loc切片是包含右边界的,但是iloc是不包含的。
5. 将Series合并为DataFrame
import pandas as pd
# 构建Series,并指定name
data = ['Jeff Russell','Jane Boorman','Tom Heints']
emps_names = pd.Series(data, index=[9001,9002,9003])
emps_names.name = 'names'
# 在构建另外一个Series,构造函数中指定name
data = ['jeff.russell','jane.boorman','tom.heints']
emps_emails = pd.Series(data, index=[9001,9002,9003], name = 'emails')
# 拼接两个Series,合并为一个dataFrame, axis指定的是合并数据的维度,axis=1表示行方向
df = pd.concat([emps_names, emps_emails], axis=1)
print(df)
这里使用Series的构造函数又创建了一个Series,并指定了name,最后通过concat方法拼接成了一个DataFrame,通过axis指定了拼接方向为横向。
6. 删除指定列
import yfinance as yf
tkr = yf.Ticker('TSLA')
hist = tkr.history(period="5d")
# 通过drop删除指定列
hist = hist.drop("Dividends", axis = 1)
hist = hist.drop("Stock Splits", axis = 1)
# reset_index用于重置索引
hist = hist.reset_index()
可以看到,我们使用drop按name删除指定列,axis为行方向。
reset_index用于重置索引,无论你设置成什么,都重置为从0开始的索引。
这样,我们便得到了一个0开始索引的DataFrame
我们可以重新设置索引,将date列设置为索引
hist = hist.set_index('Date')
索引变成了某一列的值。
7. 从JSON文本中构建DataFrame
import json
import pandas as pd
data = [{"Empno":9001,"Salary":3000},{"Empno":9002,"Salary":2800},{"Empno":9003,"Salary":2500}]
# 转json字符串
data_json = json.dumps(data)
frame = pd.read_json(data_json)
frame = frame.set_index('Empno')
print(frame)
通过json.dumps方法把数据转为json串,模拟pandas从文本中读取json串
通过read_json方法读取json串为DataFrame,并设置索引列为Empno
8. 从基础数据结构中构建DataFrame
import pandas as pd
data = [['9001','Jeff Russell', 'sales'],['9002','Jane Boorman', 'sales'],['9003','Tom Heints', 'sales']]
# 指定columns
emps = pd.DataFrame(data, columns = ['Empno', 'Name', 'Job'])
# 自定义列类型Dict
column_types = {'Empno': int, 'Name': str, 'Job': str}
# 重新转换列类型
emps = emps.astype(column_types)
# 设置索引
emps = emps.set_index('Empno')
print(emps)
这里通过DataFrame的构造函数,通过data指定数据,columns指定列名称,构建DataFrame
可以通过Dictionary的方式指定列类型,使用astype转换类型
9. 一对一合并DataFrame
一个frame有两列,索引是empno
一个frame有一列,索引也是empno
在进行合并时,属于1:1的合并,按索引合并即可
使用join完全可以实现目的:
# 反过来也可以salary.join(emps)
emps_salary = emps.join(salary)
print(emps_salary)
我们尝试给emps追加一列
# 通过dict的方式新增一个Series,name指定行索引
new_emp = pd.Series({'Name': 'John Hardy', 'Job': 'sales'}, name = 9004)
# 追加一行
emps = emps.append(new_emp)
print(emps)
这个时候,emps多了一行9004的数据,但是salary没有这个数据,再合并一下看看
emps_salary = emps.join(salary)
print(emps_salary)
哦!看起来就是数据库的left_join
其实可以通过指定how参数指定join的方式
分为left,right,inner,outer四种。left就是以左侧DataFrame为基准,right以右侧DataFrame为基准,inner是两侧DataFrame的交集,outer是两侧数据的并集。
按照这样的思路,由于salary没有9004数据,我们可以使用inner排除掉9004
emps_salary = emps.join(salary, how = 'inner')
print(emps_salary)
10. 一对多
一个DataFrame是唯一数据
一个DataFrame包含某个维度的重复数据
import pandas as pd
data = [[2608, 9001,35], [2617, 9001,35], [2620, 9001,139], [2621, 9002,95], [2626, 9002,218]]
# 构造DataFrame
orders = pd.DataFrame(data, columns = ['Pono', 'Empno', 'Total'])
print(orders)
我们发现存在相同的Empno的数据多条。
怎么合并呢?使用merge
# A merge B, inner方式,left_on左DataFrame的匹配键,right_on右DataFrame的匹配键
emps_orders = emps.merge(orders, how='inner', left_on='Empno', right_on='Empno')
# 设置index
emps_orders = emps_orders.set_index('Pono')
print(emps_orders)
我们得到了一个预期的数据
11. 分组统计
print(orders.groupby(['Empno'])['Total'].sum())
这里使用groupby进行分组,指定了按某一列分组,返回值获取total的列,组内求和。
也可以求均值
print(orders.groupby(['Empno'])['Total'].mean())