# coding:utf-8 import numpy as np import pandas as pd # Pandas 的数据结构:Pandas 主要有 # Series(一维数组), # DataFrame(二维数组), # Panel(三维数组), # Panel4D(四维数组), # PanelND(更多维数组)等数据结构。 # 其中 Series 和 DataFrame 应用的最为广泛。 # Series 是一维带标签的数组, # 它可以包含任何数据类型。包括整数,字符串,浮点数,Python 对象等。Series 可以通过标签来定位。 # DataFrame 是二维的带标签的数据结构。我们可以通过标签来定位数据。这是 NumPy 所没有的。 #================================================== # 创建 Series 数据类型 - s = pd.Series(data, index = index) #================================================== # 从列表创建 Series arr = [0,1,2,3,4] s1 = pd.Series(arr) print(s1) # 从 Ndarray 创建 Series n = np.random.randn(5) index = [‘a‘,‘b‘,‘c‘,‘d‘,‘e‘] s2 = pd.Series(n,index) print(s2) # 从字典创建 Series d = {‘a‘:1, ‘b‘:2, ‘c‘:3, ‘d‘:4,‘e‘:5} s3 = pd.Series(d) print(s3) ## Series 基本操作 # 修改 Series 索引 print(s1) s1.index = [‘A‘,‘B‘,‘C‘,‘D‘,‘E‘] # Series 纵向拼接 s4 = s3.append(s1) # Series 按指定索引删除元素 print(s4) s4 = s4.drop(‘e‘) # 删除索引为 e 的值 # Series 修改指定索引元素 s4[‘A‘] = 6 # Series 按指定索引查找元素 s4[‘B‘] # Series 切片操作 s4[:3] # 前三个元素 ##########Series 运算 # Series 加法运算 - Series 的加法运算是按照索引计算,如果索引不同则填充为 NaN(空值) s4.add(s3) # Series 减法运算 - Series的减法运算是按照索引对应计算,如果不同则填充为 NaN(空值)。 s4.sub(s3) # Series 乘法运算 s4.mul(s3) s4.div(s3) # 除法 # Series 求中位数 s4.median() s4.sum() # 求和 s4.max() # 求最大值 s4.min() # 求最小值 #================================================== # 创建 DataFrame 数据类型 #================================================== # 与 Sereis 不同,DataFrame 可以存在多列数据。一般情况下,DataFrame 也更加常用 # 通过 NumPy 数组创建 DataFrame datas = pd.date_range(‘today‘, periods = 6) num_arr = np.random.randn(6,4) columns = [‘A‘,‘B‘,‘C‘,‘D‘] df1 = pd.DataFrame(num_arr, index = datas, columns = columns) print(df1) # 通过字典数组创建 DataFrame data = { ‘animal‘:[‘cat‘, ‘cat‘, ‘snake‘, ‘dog‘, ‘dog‘, ‘cat‘, ‘snake‘, ‘cat‘, ‘dog‘, ‘dog‘], ‘age‘:[2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3], ‘visits‘:[1, 3, 2, 3, 2, 3, 1, 1, 2, 1], ‘priority‘:[‘yes‘, ‘yes‘, ‘no‘, ‘yes‘, ‘no‘, ‘no‘, ‘no‘, ‘yes‘, ‘no‘, ‘no‘] } labels = [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘, ‘h‘, ‘i‘, ‘j‘] df2 = pd.DataFrame(data, index = labels) print(df2) # 查看 DataFrame 的数据类型 df2.dtypes ######## DataFrame 基本操作 # 预览 DataFrame 的前 5 行数据 df2.head() # 默认为显示 5 行,可根据需要在括号中填入希望预览的行数 df2.tail(3) # 查看 DataFrame 的后 3 行数据 df2.index # 查看 DataFrame 的索引 df2.coulmns # 查看 DataFrame 的列名 df2.values # 查看 DataFrame 的数值 df2.describe() # 看 DataFrame 的统计数据 df2.T # DataFrame 转置操作 df2.sort_values(by=‘age‘) # 对 DataFrame 进行按列排序 df2[1:3] # 对 DataFrame 数据切片 df2[‘age‘] # 对 DataFrame 通过标签查询(单列) df2.age # 对 DataFrame 通过标签查询(单列) - # 等价于 df2[‘age‘] df2[[‘age‘,‘animal‘]] # 对 DataFrame 通过标签查询(多列) df2.iloc[1:3] # 对 DataFrame 通过位置查询 - # 查询 2,3 行 df3 = df2.copy() # DataFrame 副本拷贝 - 生成 DataFrame 副本,方便数据集被多个不同流程使用 df3.isnull() # 判断 DataFrame 元素是否为空 # 添加列数据 num = pd.Series([0,1,2,3,4,5,6,7,8], index = df3.index) df3[‘No.‘] = num # 根据 DataFrame 的下标值进行更改 # 修改第 2 行与第 1 列对应的值 3.0 → 2.0 df3.iat[1, 0] = 2 # 索引序号从 0 开始,这里为 1, 0 df3 # 根据 DataFrame 的标签对数据进行修改 df3.loc[‘f‘, ‘age‘] = 1.5 df3.mean() # DataFrame 求平均值操作 df3[‘visits‘].sum() # 对 DataFrame 中任意列做求和操作 #================================================== # 字符串操作 #================================================== # 将字符串转化为小写字母 string = pd.Series([‘A‘,‘B‘,‘C‘,‘Aaba‘, ‘Baca‘, np.nan, ‘CABA‘, ‘dog‘, ‘cat‘]) string.str.lower() string.str.upper() # 将字符串转化为大写字母 #================================================== # DataFrame 缺失值操作 #================================================== # 对缺失值进行填充 df4 = df3.copy() df4.fillna(value = 3) # 删除存在缺失值的行 df5 = df3.copy() df5.dropna(how=‘any‘) # # 任何存在 NaN 的行都将被删除 # DataFrame 按指定列对齐 left = pd.DataFrame({‘key‘: [‘foo1‘, ‘foo2‘], ‘one‘: [1, 2]}) right = pd.DataFrame({‘key‘: [‘foo2‘, ‘foo3‘], ‘two‘: [4, 5]}) print(left) print(right) # 按照 key 列对齐连接,只存在 foo2 相同,所以最后变成一行 pd.merge(left, right, on=‘key‘) #================================================== # DataFrame 文件操作 #================================================== # CSV 文件写入 df3.to_csv(‘animal.csv‘) print("写入成功.") # CSV 文件读取 df_animal = pd.read_csv(‘animal.csv‘) # Excel 写入操作 df3.to_excel(‘animal.xlsx‘, sheet_name=‘Sheet1‘) # Excel 读取操作 pd.read_excel(‘animal.xlsx‘, ‘Sheet1‘, index_col=None, na_values=[‘NA‘]) #================================================== # 进阶部分 #================================================== ######### 时间序列索引 # 建立一个以 2018 年每一天为索引,值为随机数的 Series dti = pd.date_range(start=‘2018-01-01‘, end=‘2018-12-31‘, freq=‘D‘) s = pd.Series(np.random.rand(len(dti)), index=dti) # 统计s 中每一个周三对应值的和 s[s.index.weekday == 2].sum() # 统计s中每个月值的平均值 s.resample(‘M‘).mean() # 将 Series 中的时间进行转换(秒转分钟) s = pd.date_range(‘today‘, periods=100, freq=‘S‘) ts = pd.Series(np.random.randint(0, 500, len(s)), index=s) ts.resample(‘Min‘).sum() # UTC 世界时间标准 s = pd.date_range(‘today‘, periods=1, freq=‘D‘) # 获取当前时间 ts = pd.Series(np.random.randn(len(s)), s) # 随机数值 ts_utc = ts.tz_localize(‘UTC‘) # 转换为 UTC 时间 # 转换为上海所在时区 ts_utc.tz_convert(‘Asia/Shanghai‘) # 不同时间表示方式的转换 rng = pd.date_range(‘1/1/2018‘, periods = 5, freq = ‘M‘) ts = pd.Series(np.random.randn(len(rng)),index=rng) print(ts) ps = ts.to_period() print(ts) ps.to_timestamp() ######## Series 多重索引 # 创建多重索引 Series letters = [‘A‘, ‘B‘, ‘C‘] numbers = list(range(10)) mi = pd.MultiIndex.from_product([letters, numbers]) # 设置多重索引 s = pd.Series(np.random.rand(30), index=mi) # 随机数 # 多重索引 Series 查询 s.loc[:,[1,3,6]] s.loc[pd.IndexSlice[:‘B‘, 5:]] # 多重索引 Series 切片 ############## DataFrame 多重索引 # 根据多重索引创建 DataFrame # - 创建一个以 letters = [‘A‘, ‘B‘] 和 numbers = list(range(6))为索引, # 值为随机数据的多重索引 DataFrame frame = pd.DataFrame(np.arange(12).reshape(6,2), index = [list(‘AAABBB‘), list(‘123123‘)], columns = [‘hello‘, ‘shiyanlou‘]) # 多重索引设置列名称 frame.index.names = [‘first‘, ‘second‘] # DataFrame 多重索引分组求和 frame.groupby(‘first‘).sum() # DataFrame行列名称转换 frame.stack() # DataFrame 索引转换 frame.unstack() # DataFrame 条件查找 data = {‘animal‘: [‘cat‘, ‘cat‘, ‘snake‘, ‘dog‘, ‘dog‘, ‘cat‘, ‘snake‘, ‘cat‘, ‘dog‘, ‘dog‘], ‘age‘: [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3], ‘visits‘: [1, 3, 2, 3, 2, 3, 1, 1, 2, 1], ‘priority‘: [‘yes‘, ‘yes‘, ‘no‘, ‘yes‘, ‘no‘, ‘no‘, ‘no‘, ‘yes‘, ‘no‘, ‘no‘]} labels = [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘, ‘h‘, ‘i‘, ‘j‘] df = pd.DataFrame(data, index=labels) df[df[‘age‘] > 3] # 查找 age 大于 3 的全部信息 df.iloc[2:4, 1:3] #根据行列索引切片 # DataFrame 多重条件查询 df = pd.DataFrame(data, index=labels) df[(df[‘animal‘] == ‘cat‘) & (df[‘age‘] < 3)] # DataFrame 按关键字查询 df3[df3[‘animal‘].isin([‘cat‘, ‘dog‘])] # DataFrame 按标签及列名查询 df.loc[df2.index[[3, 4, 8]], [‘animal‘, ‘age‘]] ### DataFrame 多条件排序 ## 按照 age 降序,visits 升序排列 df.sort_values(by=[‘age‘, ‘visits‘], ascending=[False, True]) # DataFrame 多值替换 df[‘priority‘].map({‘yes‘: True, ‘no‘: False}) # DataFrame 分组求和 df4.groupby(‘animal‘).sum() # 使用列表拼接多个 DataFrame temp_df1 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 1 temp_df2 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 2 temp_df3 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 3 pieces = [temp_df1, temp_df2, temp_df3] pd.concat(pieces) # 找出 DataFrame 表中和最小的列 df = pd.DataFrame(np.random.random(size=(5, 10)), columns=list(‘abcdefghij‘)) df.sum().idxmin() # DataFrame 中每个元素减去每一行的平均值 df = pd.DataFrame(np.random.random(size=(5, 3))) print(df) df.sub(df.mean(axis=1), axis=0) # DataFrame 分组,并得到每一组中最大三个数之和 df = pd.DataFrame({‘A‘: list(‘aaabbcaabcccbbc‘), ‘B‘: [12, 345, 3, 1, 45, 14, 4, 52, 54, 23, 235, 21, 57, 3, 87]}) print(df) df.groupby(‘A‘)[‘B‘].nlargest(3).sum(level=0) ######### 透视表 # - 当分析庞大的数据时, # 为了更好的发掘数据特征之间的关系,且不破坏原数据,就可以利用透视表 pivot_table 进行操作 # 新建表将 A, B, C 列作为索引进行聚合 df = pd.DataFrame({‘A‘: [‘one‘, ‘one‘, ‘two‘, ‘three‘] * 3, ‘B‘: [‘A‘, ‘B‘, ‘C‘] * 4, ‘C‘: [‘foo‘, ‘foo‘, ‘foo‘, ‘bar‘, ‘bar‘, ‘bar‘] * 2, ‘D‘: np.random.randn(12), ‘E‘: np.random.randn(12)}) print(df) pd.pivot_table(df, index=[‘A‘, ‘B‘]) # 透视表按指定行进行聚合 # 将该 DataFrame 的 D 列聚合,按照 A,B 列为索引进行聚合,聚合的方式为默认求均值 pd.pivot_table(df, values=[‘D‘], index=[‘A‘, ‘B‘]) # 透视表聚合方式定义 # 上一题中 D 列聚合时,采用默认求均值的方法,若想使用更多的方式可以在 aggfunc 中实现。 pd.pivot_table(df, values=[‘D‘], index=[‘A‘, ‘B‘], aggfunc=[np.sum, len]) # 透视表利用额外列进行辅助分割 pd.pivot_table(df, values=[‘D‘], index=[‘A‘, ‘B‘], columns=[‘C‘], aggfunc=np.sum) # 透视表的缺省值处理 # 在透视表中由于不同的聚合方式,相应缺少的组合将为缺省值,可以加入 fill_value 对缺省值处理 pd.pivot_table(df, values=[‘D‘], index=[‘A‘, ‘B‘], columns=[‘C‘], aggfunc=np.sum, fill_value=0) ####### 绝对类型 # 在数据的形式上主要包括数量型和性质型, # 数量型表示着数据可数范围可变,而性质型表示范围已经确定不可改变, # 绝对型数据就是性质型数据的一种 # 绝对型数据定义 df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6], "raw_grade": [ ‘a‘, ‘b‘, ‘b‘, ‘a‘, ‘a‘, ‘e‘]}) df["grade"] = df["raw_grade"].astype("category") # 对绝对型数据重命名 df["grade"].cat.categories = ["very good", "good", "very bad"] # 重新排列绝对型数据并补充相应的缺省值 df["grade"] = df["grade"].cat.set_categories( ["very bad", "bad", "medium", "good", "very good"]) df # 对绝对型数据进行排序 df.sort_values(by="grade") # 对绝对型数据进行分组 df.groupby("grade").size() ##### 数据清洗 ‘‘‘ 常常我们得到的数据是不符合我们最终处理的数据要求, 包括许多缺省值以及坏的数据,需要我们对数据进行清洗 ‘‘‘ # 缺失值拟合 # 在FilghtNumber中有数值缺失, # 其中数值为按 10 增长,补充相应的缺省值使得数据完整,并让数据为 int 类型 df = pd.DataFrame({‘From_To‘: [‘LoNDon_paris‘, ‘MAdrid_miLAN‘, ‘londON_StockhOlm‘, ‘Budapest_PaRis‘, ‘Brussels_londOn‘], ‘FlightNumber‘: [10045, np.nan, 10065, np.nan, 10085], ‘RecentDelays‘: [[23, 47], [], [24, 43, 87], [13], [67, 32]], ‘Airline‘: [‘KLM(!)‘, ‘<Air France> (12)‘, ‘(British Airways. )‘, ‘12. Air France‘, ‘"Swiss Air"‘]}) df[‘FlightNumber‘] = df[‘FlightNumber‘].interpolate().astype(int) # 数据列拆分 temp = df.From_To.str.split(‘_‘, expand=True) temp.columns = [‘From‘, ‘To‘] # 字符标准化 temp[‘From‘] = temp[‘From‘].str.capitalize() temp[‘To‘] = temp[‘To‘].str.capitalize() # 删除坏数据加入整理好的数据 # 将最开始的 From_to 列删除,加入整理好的 From 和 to 列。 df = df.drop(‘From_To‘, axis=1) df = df.join(temp) print(df) # 去除多余字符 # 如同 airline 列中许多数据有许多其他字符, # 会对后期的数据分析有较大影响,需要对这类数据进行修正 df[‘Airline‘] = df[‘Airline‘].str.extract( ‘([a-zA-Z\s]+)‘, expand=False).str.strip() # 格式规范 # 在 RecentDelays 中记录的方式为列表类型, # 由于其长度不一,这会为后期数据分析造成很大麻烦。 # 这里将 RecentDelays 的列表拆开,取出列表中的相同位置元素作为一列, # 若为空值即用 NaN 代替。 delays = df[‘RecentDelays‘].apply(pd.Series) delays.columns = [‘delay_{}‘.format(n) for n in range(1, len(delays.columns)+1)] df = df.drop(‘RecentDelays‘, axis=1).join(delays) ##### 数据预处理 # 信息区间划分 # 班级一部分同学的数学成绩表,如下图所示 df = pd.DataFrame({‘name‘: [‘Alice‘, ‘Bob‘, ‘Candy‘, ‘Dany‘, ‘Ella‘, ‘Frank‘, ‘Grace‘, ‘Jenny‘], ‘grades‘: [58, 83, 79, 65, 93, 45, 61, 88]}) def choice(x): if x > 60: return 1 else: return 0 df.grades = pd.Series(map(lambda x: choice(x), df.grades)) # 数据去重 df = pd.DataFrame({‘A‘: [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]}) df.loc[df[‘A‘].shift() != df[‘A‘]] # 数据归一化 def normalization(df): numerator = df.sub(df.min()) denominator = (df.max()).sub(df.min()) Y = numerator.div(denominator) return Y df = pd.DataFrame(np.random.random(size=(5, 3))) print(df) normalization(df) ###### Pandas 绘图操作 # Series 可视化 # %matplotlib inline ts = pd.Series(np.random.randn(100), index=pd.date_range(‘today‘, periods=100)) ts = ts.cumsum() ts.plot() # DataFrame 折线图 df = pd.DataFrame(np.random.randn(100, 4), index=ts.index, columns=[‘A‘, ‘B‘, ‘C‘, ‘D‘]) df = df.cumsum() df.plot() # DataFrame 散点图 df = pd.DataFrame({"xs": [1, 5, 2, 8, 1], "ys": [4, 2, 1, 9, 6]}) df = df.cumsum() df.plot.scatter("xs", "ys", color=‘red‘, marker="*") # DataFrame 柱形图 df = pd.DataFrame({"revenue": [57, 68, 63, 71, 72, 90, 80, 62, 59, 51, 47, 52], "advertising": [2.1, 1.9, 2.7, 3.0, 3.6, 3.2, 2.7, 2.4, 1.8, 1.6, 1.3, 1.9], "month": range(12) }) ax = df.plot.bar("month", "revenue", color="yellow") df.plot("month", "advertising", secondary_y=True, ax=ax)
原文:https://www.cnblogs.com/zhaxichun/p/10841801.html