Numpy 中的基础数据结构是 array(数组),数组也就是矩阵的意思。
一维数组是行向量,二维数组是列向量/矩阵;
三维数组是在时间轴上的二维数组,三维和高维的数组通常用的不多。
(1)关于np.array的常见操作:
>>> import numpy as np
>>> import pandas as pd
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
[4, 5, 6]])
>>> # 数组的维度
>>> a.shape
(2, 3)
>>> # 将二维数组转成一维数组
>>> a.ravel()
array([1, 2, 3, 4, 5, 6])
>>> # 改变二维数组形状
>>> a.reshape((3,2))
array([[1, 2],
[3, 4],
[5, 6]])
>>> a.shape
(2, 3)
(2)关于np.random的常见操作:
>>> # 在[0,1)内产生随机数,维度是3*2
>>> np.random.random((3,2))
array([[0.63884278, 0.02508707],
[0.71119818, 0.10008103],
[0.68718291, 0.2778071 ]])
>>> # 产生指定区间的随机整数,维度是3*2
>>> np.random.randint(low=2, high=10, size=(3,2))
array([[8, 3],
[2, 6],
[2, 9]])
>>> # 均匀分布
>>> np.random.uniform(low=3, high=10, size=(3,2))
array([[9.16399837, 5.75987948],
[7.02144694, 8.47427805],
[7.38052989, 8.4861068 ]])
同大部分的数据分析库一样,Pandas 的核心也是 Numpy,
Pandas是在Numpy基础上封装了高级接口,使得Pandas能处理包括数值型,字符串,日期等多种数据类型,
提供了统计分析函数、日期处理函数、表格数据整理等,可大大提高数据分析的效率。
Pandas 包含两种基础数据结构:Series 和(更全面的)DataFrame
所以DataFrame是由多个Series组成的,虽然这些series的索引相同(行数相同),但其名称(列名)不同。
类似于字典结构,包括索引(字典中的“键”)和值(字典中的“值”)。
创建Series 的基初方式:
>>> index = ['2019/3/23', '2019/3/24', '2019/3/25', '2019/3/26',
'2019/3/27', '2019/3/28', '2019/3/29', '2019/3/30',
'2019/3/31', '2019/4/1', '2019/4/2', '2019/4/3', '2019/4/4']
>>> value = [18, 20, 19, 20, 18, 15, 17, 19, 20, 15, 18, 15, 20]
>>> # 如果不指定索引,会自动生成0,1,2,....这样的索引
>>> s = pd.Series(data=value, index=index)
>>> s
2019/3/23 18
2019/3/24 20
2019/3/25 19
2019/3/26 20
2019/3/27 18
2019/3/28 15
2019/3/29 17
2019/3/30 19
2019/3/31 20
2019/4/1 15
2019/4/2 18
2019/4/3 15
2019/4/4 20
dtype: int64
DataFrame是数据分析的基础。DataFrame本质就是一张表,比如一张Excel就是一个DataFrame。
DataFrame中可以包含不同种数据结构,也就是说,不同的列可以是不同的数据类型。
>>> # 创建方式 1:生成3*5维度的随机数
>>> df = pd.DataFrame(np.random.rand(3,5), columns=list('ABCDE'))
>>> df
A B C D E
0 0.894839 0.282546 0.847286 0.717782 0.139152
1 0.520363 0.989707 0.177874 0.997028 0.505094
2 0.168431 0.174067 0.740026 0.174544 0.328101
>>> # 创建方式 2:通过字典创建,字典中的键表示DaTaFrame的列名,值是对应的值
>>> df = pd.DataFrame(data={
'学号': ['001', '002', '003', '004', '005'],
'姓名': ['dog', 'cat', 'tiger', 'lion', 'rabbit'],
'身高': [177, 151, 167, 175, 153],
'成绩': [92, 84, 80, 77, 87]})
>>> # 创建方式 3:通过嵌套的list创建,需要额外指定列名。
>>> df = pd.DataFrame(data=[
['001', 'dog', 177, 92],
['002', 'cat', 151, 84],
['003', 'tiger', 167, 80],
['004', 'lion', 175, 77],
['005', 'rabbit', 153, 87]],
columns=['学号', '姓名', '身高', '成绩'])
# 查看dataframe的维度
>>> df.shape
# 最大值最小值
>>> df['列名'].max()
>>> df['列名'].min()
# 均值和标准差
>>> df['列名'].mean()
>>> df['列名'].std()
# 分位数:90%的分位数
>>> df['列名'].quantile(q=0.9)
# 累计值
>>> df['列名'].cumsum()
# 相关系数
>>> df[['列名1','列名2']].corr(methord='pearson')
# 协方差
>>> df[['列名1','列名2']].cov()
数据清洗:如缺失值、异常值处理,
删除重复记录,排序,列的重命名、添加、删除等等。
# 列的增删改
df = df.rename(columns={'列名':'新列名'}) # 重命名列名
df['新列名']=[1,2,3,4,5] # 添加列(法1):前面为列名,后边为值
df['新列名']=df['成绩']*0.8 # 添加列(法2):在原有列的基础上生成
df.drop(columns=['列名']) # 删除列(法1):实际中用的多
del df['列名'] # 删除列(法2)
# 子集选择,loc读取的是索引;iloc读取的是行数
df.loc[2:4] # 选择索引范围在[2,4]的数据,即第3到第5行
df.iloc[1:4] # 选择第2到第4行(对应索引为1-3)
# 选择身高>160且成绩>80的数据,只要"姓名","学分","日期"3列
df.loc[(df['身高']>160) & (df['成绩']>80), ["姓名","学分","日期"]]
# 根据成绩降序排序,inplace=True替换之前的df
df.sort_values(by=['成绩'], ascending=True)
# 缺失值处理,一般用fillna填充
df.loc[(df['姓名']=='张三'), '成绩']=np.NaN #先将张三成绩替换成缺失值(numpy.NaN),然后填充为80分
df['成绩'] = df['成绩'].fillna(80)
df['成绩'] = df['成绩'].fillna(df['成绩'].mean())#均值填充
# 异常值处理
abnormal = df['语文成绩'].mean() + 2*df['语文成绩'].std()
df.loc[df['成绩'] > abnormal, '成绩'] = abnormal # 将大于“均值+2倍标准差”的认为是异常值,用“均值+2倍标准差”代替
# 删除重复记录——用的也比较多
# 根据“姓名,学号”判断是否重复,若重复则删除重复记录,只保留一条记录
df = df.drop_duplicates(subset=['姓名','学号'])
groupby() 函数,参数as_index=False表示统计后返回DataFrame类型的结果,否则返回Series类型的结果。
>>> df = pd.DataFrame(data = {
'grade':[1,2,1,3,2,2,3],
'class':[1,1,2,1,2,2,1],
'sname':['dog','cat','rabbit','bird','lion','tiger','fish'],
'sex':['boy','girl','boy','girl','girl','boy','girl'],
'score':[80,70,85,90,88,93,95]})
>>> df
grade class sname sex score
0 1 1 dog boy 80
1 2 1 cat girl 70
2 1 2 rabbit boy 85
3 3 1 bird girl 90
4 2 2 lion girl 88
5 2 2 tiger boy 93
6 3 1 fish girl 95
>>> df.groupby(by=['grade','class'], as_index=False)['sname'].count() # 查询每个班的人数
>>> df.groupby(by=['grade','class'], as_index=False)['score'].mean() # 查询每个班的平均成绩
>>> df.groupby(by=['grade'], as_index=False)['score'].sum() # 查询每个年级的总成绩
# 计算每班最高分
>>> def myfunc(series):
... return 'max:' + str(series.max())
>>> df.groupby(by=['class'], as_index=False)['score'].agg(myfunc)
class score
0 1 max:95
1 2 max:93
>>> df.groupby(by=['class'], as_index=False)['score'].apply(myfunc)
class score
0 1 max:95
1 2 max:93
>>>
apply()括号中放的是函数,且接收的是pandas.Series类型。
# 对姓名这一列的每个元素添加字母'haha'
>>> def myfun(x) :
return 'haha' + x
>>> df['sname'].apply(myfunc)
# 对成绩这一列,如果成绩小于90分则改成90
>>> def myfunc(x):
if x<90:
return 90
else:
turn x
>>> def['score'].apply(myfunc)