为什么要用Pandas
Pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。
pandas的主要特点
- 基于Numpy创建,继承了Numpy中优秀的特点;
- 能够直接读取结构化数据进行操作;
- 以类似于表格的形式呈现数据,便于观察;
- 提供了大量的数理统计方法。
Pandas的两种数据结构
- Series:带标签的一维同构数组;
- DataFrame:带标签的,大小可变的,二维异构表格。
按照层级关系来说的话,可以说DataFrame是Series的容器,Series是标量的容器。先来看一下如何去创建数据。
数据的创建
# 创建Series import numpy as np import pandas as pd s = pd.Series([1, 3, 5, 7, np.nan]) print(type(s)) print(s)
# 使用时间索引以及带标签的Numpy数组创建DataFrame dates = pd.date_range('20200501', periods=6) # print(datas) df1 = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list("ABCD")) print(type(df1)) print(df1)
# 使用Series字典对象生成DataFrame df2 = pd.DataFrame({ 'A': 1., 'B': pd.Timestamp('20200501'), 'C': pd.Series(1, index=list(range(4)), dtype='float32'), 'D': np.array([3] * 4, dtype='int32'), 'E': pd.Categorical(["test", "train", "test", "train"]), 'F': 'foo' }) print(type(df2)) print(df2)
# 判断不同的列的数据类型 df2.dtypes
查看数据
# 查看头部和尾部数据(可以传参) df1.head() # 查看头部数据,默认为前五行 df1.tail() # 查看尾部数据,默认为后五行
# 查看索引与列名 df1.index # 查看索引 df1.columns # 查看列名
# 查看整体统计信息 df1.info() # 查看数据的统计摘要 df1.describe() # 数据的转置(列和行进行互换) df1.T # 按照标签排序 # axis:0按照行名排序;1按照列名排序 # ascending:默认True升序排列;False降序排列 df1.sort_index(axis=1, ascending=False) # 按照值排序 # axis:default 0,默认按照列排序,即纵向排序;如果为1,则是横向排序。 # by:如果axis=0,那么by="列名";如果axis=1,那么by="行名"。 df1.sort_values(by='B')
# 将df转化为array df1.to_numpy()
一般的选择数据
# 直接获取数据 df1['A'] # 按照索引值切片行数据 df1[0:3] # 按照索引名称切片行数据(首尾都可以获取) df1['20200501':'20200503']
按标签选择数据
# 提取某行数据 df1.loc[dates[0]] # 按照标签选择多列数据 df1.loc[:, ['A', 'B']] # 使用切片获取部分数据(也可以获取一个数值) df1.loc['20200502':'20200504', ['A', 'B']]
按位置选择数据
# 使用索引值位置选择 df1.iloc[3] # 使用切片的方式批量选择 df1.iloc[3:5, 0:2] # 使用索引值位置列表选择 df1.iloc[[1, 2, 4], [0, 2]]
按照条件选择数据
# 用单列的值选择数据 df1[df1.A>0] # 选择df中满足条件的值(不满足会现实NaN) df1[df1>0] # 使用isin()选择 df2[df2['E'].isin(['test'])]
赋值
# 按照标签赋值 df1.at[dates[0], 'A'] = 0 # 按照位置赋值 df1.iat[0, 1] = 1 # 条件赋值 df1[df1 > 0] = 2
替换索引(数据)
# 强行修改源数据命名索引 df2.set_axis(list('abcd'), inplace=True) # 更灵活的修改索引(提供了inplace方法设置是否修改源数据) df2.rename(index={'a': 'aa', 'b': 'bb'}, columns={'A': 'AA'}) # 修改数据的方法(列表) df2.replace(['test', 'train'], ['apple', 'banana']) # 修改数据的方法(字典) df2.replace({'test': 'apple', 'train': 'banana'}) # 填充缺失值 # df2.fillna()
删除数据
# 删除具体列 df2.drop('A', axis=1) # 删除具体的行 df2.drop('a', axis=0) # 根据索引值进行删除 df2.drop(df2.index[3]) # 删除缺失值 df2.dropna() # 去除重复值 df2.drop_duplicates() # 按照条件删除数据 df2[df2.E == 'test'] # 删除某列包含特殊字符的行 df2[~df2.E.str.contains('te')] # 取包含某些字符的记录 df2[df2.E.str.contains('te')]
数据的合并
# 结合数据concat() df3 = pd.DataFrame(np.random.randn(10, 4)) pieces = [df3[:3], df3[3:7], df3[7:]] pd.concat(pieces) # pd.concat([df3[:3], df3[3:7], df3[7:]]) # 连接数据merge() left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]}) right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]}) pd.merge(left, right, on='key') # 追加数据append() df4 = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D']) s = df4.iloc[3] df4.append(s, ignore_index=True)
数据分组
df5 = pd.DataFrame({ 'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C': np.random.randn(8), 'D': np.random.randn(8) }) # 正常的分组 # 我们不能直接查看分组后的结果,要进行一些其他的操作 df5.groupby('A') # 根据分组统计数值和 df5.groupby('A').sum() # 对分组进行迭代 for name, group in df5.groupby('B'): print(name) print(group) # 将分组结果转换为字典 piece = dict(list(df5.groupby('B')))
apply函数
apply()函数会遍历每一个元素,对元素运行指定的function,具体的用法如下所示:
# 进行矩阵的平方运算 matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] df6 = pd.DataFrame(matrix, columns=list('xyz'), index=list('abc')) df6.apply(np.square) # 使用lambda函数进行运算(运算指定的行或列) df6.apply(lambda x: np.square(x) if x.name == 'x' else x)