赞
踩
pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
Pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)
from pandas import Series import numpy as np # 类似一维数组 # 1.使用列表创建: s = Series(data = [94, 54, 80]) # 使用列表创建 只给定values, 默认index print(type(s)) # Series s = Series(data = [94, 54, 80], index=['语文','数学', '英语']) # 给定values和index print(s) # 打印对象,重写了__str__()方法 ''' 语文 94 数学 54 英语 80 dtype: int64 ''' # 2.使用ndarray创建 nd = np.random.randint(1, 10, size=5) s = Series(data=nd) print(s) # 3.使用字典创建 s = Series({'语文':90, '数学':88, '英语':89}) # 其索引为keys print(s) print(s.index) # Index(['语文', '数学', '英语'], dtype='object') # ''' # 语文 90 # 数学 88 # 英语 89 # dtype: int64 # ''' 使用列表、字典与ndarray创建的区别: 由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(字典、列表没有这种情况)
from pandas import Series
# 二、Series的属性
s = Series({'语文':88, '数学':89, '英语':90})
print(s.index) # Index(['语文', '数学', '英语'], dtype='object') 索引
print(s.values, type(s.values)) # [88 89 90] ndarray 值域
print(s.shape) # (3,) 一维,有三个元素
print(s.size) # 3 元素的个数
# 三、Series的索引和切片 from pandas import Series # 索引 s = Series({'语文':88, '数学':89, '英语':90}) # (1)显式索引的两种写法 print(s['英语'],) # 90 直接写中括号 print(s.loc['语文']) # 88 第二种,使用loc[], location 推荐写法. # (2) 隐式索引: # - 使用整数作为索引值 # - 使用.iloc[](推荐) print(s[0]) # 88 print(s.iloc[1]) # 89 # 使用loc与iloc主要是为了当Series的index为0、1..时的发生的歧义 # (3) 使用get(),当元素不存在的时候返回None s.get('语文') # 88 s.get('语文1') # None # (4)特殊: # 索引时再加一个中括号,返回Series类型 print(type(s.loc[['语文']])) # <class 'pandas.core.series.Series'> print('\n******切片******\n') # 切片 # (1)显式索引切片, # 全闭区间 print(s['语文':'数学']) print(s.loc['语文':'数学']) # ''' # 语文 88 # 数学 89 # dtype: int64 # ''' print('**********') # (2) 隐式索引切片:# 左闭右开 print(s[0:2]) # 88 print(s.iloc[0:2]) # 89 # 语文 88 # 数学 89 # dtype: int64
# 四、Series 常用方法 import pandas as pd from pandas import Series s = Series({'语文':88, '数学':89, '英语':90}) #(1) 获取前n个,默认前5行 print(s.head(2)) #(2) 获取后n个,默认后5行 print(s.tail(2)) # 当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况 s = Series({'语文':88, '数学':89, '英语':90, '体育':None}) pd.isnull(s) # 判断values是不是NAN,返回Series, values为True或False s.isnull() # 同上 pd.notnull(s) # 判断values不是nan,返回Series s.notnull() # 同上 ''' 语文 False 数学 False 英语 False 体育 True dtype: bool '''
# 五、Series 增加删除修改元素
s = Series({'语文':88, '数学':89, '英语':90})
s.loc['语文'] = 90 # 修改元素
a = s.pop('英语') # 删除元素
print(a) # 90
s = s.append(Series({'py':80})) # 增加元素,需要另一个series
print(s)
# 六、Series的运算 # 1)Series与数字和字符串的运算 s = Series({'语文':'88', '数学':'89', '英语':'90'}) s+'1' # 所有values都拼接,数字的话都加 # 2)Series之间的运算 # 在运算中自动对齐不同索引的数据 # 如果索引不对应,则补NaN # Series没有广播机制 Series根据相同的索引进行运算索引不同补NaN s1 = Series({'语文':88, '数学':89, '英语':90}) s2 = Series({'语文':88, '数学':89, 'py':90}) s1 + s2 ''' py NaN 数学 178.0 英语 NaN 语文 176.0 dtype: float64 ''' s1 = Series({'语文':88, '数学':89, '英语':90}) s2 = Series({'语文':88, '数学':89, 'py':90}) s1.add(s2, fill_value=0) # 保留所有的value,则需要使用.add()函数, fill_value给定填充值 ''' py 92.0 数学 178.0 英语 92.0 语文 176.0 dtype: float64 '''
from pandas import DataFrame import numpy as np # DataFrame可以看做是【由Series组成的字典】 # 其初衷是将Series的使用场景从一维拓展到多维。 # DataFrame既有行索引,也有列索引。 # 创建DataFrame, 推荐使用 index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语'] data = np.random.randint(0, 150, size=(4,3,)) df = DataFrame(data=data, index=index, columns=columns) print(df, type(df)) # DataFrame ''' 语文 数学 英语 张三 119 97 25 李四 72 65 52 王五 112 87 101 赵六 142 85 133 <class 'pandas.core.frame.DataFrame'> ''' # 字典创建DataFrame, 字典的key是列索引 df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) # df.index = ['张三', '李四', '王五', '赵六'] print(df, type(df)) ''' 语文 数学 英语 python 张三 6 13 121 3 李四 0 73 36 109 王五 127 135 4 7 赵六 94 126 146 139 <class 'pandas.core.frame.DataFrame'> '''
# DataFrame的属性 df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) print(df.index) # 行索引 # Index(['张三', '李四', '王五', '赵六'], dtype='object') print(df.columns) # 列索引 # Index(['语文', '数学', '英语', 'python'], dtype='object') print(df.values) # 值域 ''' [[ 6 20 113 89] [ 46 25 11 133] [ 12 74 123 55] [ 0 142 121 62]] ''' print(df.shape) # (4, 4)
index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语'] data = np.random.randint(0, 150, size=(4,3,)) df = pd.DataFrame(data=data, index=index, columns=columns) # 增加行 df.loc['田七'] = [78, 88, 90] df # 增加列 df['python'] = [88, 76, 90, 88] df # 删除行 df.drop('田七', inplace=True) df # 删除列 df.drop('python', axis=1, inplace=True) df # 改具体某个值 df.loc['张三', '英语'] = 100 df # 当给某一列赋值给某变量时,如果后期需要修改这个变量的值而且要影响原dataframe,要使用深拷贝copy data = df[['英语']].copy() data['英语'] = data['英语'] + 1 df
# DataFrame的索引与切片 (1) 对列进行索引 - 通过类似字典的方式 - 通过属性的方式 可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引, 且name属性也已经设置好了,就是相应的列名 df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) print(df['语文'], type(df['语文'])) # Series ''' 张三 42 李四 44 王五 23 赵六 13 Name: 语文, dtype: int32 <class 'pandas.core.series.Series'> ''' print(df[['语文', '数学']], type(df[['语文']])) # 再加一层中括号,变为DataFrame ''' 语文 数学 张三 42 139 李四 44 80 王五 23 35 赵六 13 21 <class 'pandas.core.frame.DataFrame'> ''' df['理综'] = np.random.randint(0,300, size=4) # 新增一列 (2) 对行进行索引 - 使用.loc[]加index来进行行索引 - 使用.iloc[]加整数来进行行索引 同样返回一个Series,index为原来的columns。 df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) # 显示行索引 print(df.loc['李四'], type(df.loc['李四'])) # 只能单个 ''' 语文 56 数学 102 英语 106 python 94 Name: 李四, dtype: int32 <class 'pandas.core.series.Series'> ''' print(df.loc[['张三','李四']], type(df.loc[['张三','李四']])) # 可以多个 ''' 语文 数学 英语 python 张三 9 78 137 66 李四 119 17 48 50 <class 'pandas.core.frame.DataFrame'> ''' # 隐式行索引 print(df.iloc[0], type(df.iloc[0])) ''' 语文 125 数学 143 英语 117 python 126 Name: 张三, dtype: int32 <class 'pandas.core.series.Series'> ''' print(df.iloc[[0,2]], type(df.iloc[[0,2]])) ''' 语文 数学 英语 python 张三 125 143 117 126 王五 48 36 52 93 <class 'pandas.core.frame.DataFrame'> ''' df.loc['田七'] = np.random.randint(0,150, size=4) # 新增一行 (3) 对元素索引的方法 - 使用列索引 - 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数) - 使用values属性(二维numpy数组) df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) print(df) ''' 语文 数学 英语 python 张三 49 57 4 41 李四 120 135 110 75 王五 120 41 148 91 赵六 128 129 40 5 ''' print(df['语文'].loc['张三']) # 49 先列索引,返回Series, 再索引到具体某个人 print(df['语文']['张三']) # 49 同上 print(df.loc['王五'].loc['数学']) # 41 先行索引,返回Series, 再索引到具体某科目 print(df.loc['王五']['数学']) # 41 同上 # 优化写法 推荐写法 print(df.loc['王五', '数学']) # 41 具体定位 display(df.loc[['张三'], ['数学']]) # 返回dataframe
(1) 行切片 1.直接使用中括号对DataFrame 进行切片的时候,执行的 是行切片. print(df['张三':'李四']) 2.使用显式索引进行行切片. print(df.loc['张三': '王五']) 3.使用隐式索引进行行切片. print(df.iloc[1:3]) df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) print(df) ''' 语文 数学 英语 python 张三 105 68 117 118 李四 119 74 106 34 王五 20 94 86 60 赵六 98 140 37 8 ''' print(df['张三':'李四']) # 直接使用中括号对DataFrame进行切片的时候,执行的是行切片. ''' 语文 数学 英语 python 张三 105 68 117 118 李四 119 74 106 34 ''' print(df.loc['张三':'王五']) ''' 语文 数学 英语 python 张三 20 101 79 142 李四 103 16 90 110 王五 95 121 47 32 ''' print(df.iloc[1:3]) (2) 列切片: 1.使用显式索引进行列切片. print(df.loc[:, '语文':'数学']) 2.对列进行隐式切片 print(df.iloc[:, 1:3]) print(df.loc[:, '语文':'数学']) ''' 语文 数学 张三 126 21 李四 135 67 王五 48 24 赵六 67 21 ''' print(df.iloc[:, 1:3]) ''' 数学 英语 张三 51 36 李四 147 21 王五 59 130 赵六 146 125 ''' 总结: 1, 行索引永远用.loc[] 2, 列索引用于用[] 3, 索引元素的时候,先找行再找列,使用.loc[index, column] 4, 切片的时候,直接使用中括号是对行切片 , 对列进行切片也需要先从行开始 .loc[:, column: column]
(1)DataFrame之间的运算 同Series一样: 在运算中自动对齐不同索引的数据 如果索引不对应,则补NaN df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) df2 = df.copy() df + df2 # 如果索引不对应,则补NaN, NaN与任何数相加都得NaN 如果要保留原始数据则使用add()、sub()、mul()、div() --加减乘除 df.add(df2, fill_value=0) # fill_value 索引不对称, 填充0 (2) Series与DataFrame之间的运算 【重要】 使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。 (类似于numpy中二维数组与一维数组的运算,但可能出现NaN) df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)}, index = ['张三', '李四', '王五', '赵六']) s = Series(index=['语文', '数学', '英语', 'python', '文综'], data=np.random.randint(0,150, size=(5))) df + s # 以行为单位操作,对所有行都有效 s2 = Series(index=['张三', '李四', '王五', '赵六', '田七'], data=np.random.randint(0,150, size=(5))) df.add(s, axis='columns') # 以行为单位操作,对所有行都有效 df.add(s, axis='index') # 以列为单位操作,对所有列都有效 # 不能有fill_values 总结: DataFrame和Series进行运算的时候,默认是按照DataFrame的列索引进行操作, 列索引一致才进行运算,列索引不一致补NaN. 可以通过pandas封装的运算函数的axis来修改操作的方向.
(1).pandas中的None与NaN【pandas中None与np.nan都视作np.nan】 df = DataFrame({'语文': np.random.randint(0,150, size=3), '数学': np.random.randint(0,150, size=3), '英语': np.random.randint(0,150, size=3), 'python': np.random.randint(0,150, size=3)}, index = ['张三', '李四', '王五']) df.loc['张三', '数学'] = np.nan df.loc['李四', '英语'] = None ''' 语文 数学 英语 python 张三 20 NAN 79 142 李四 103 16 NAN 110 王五 95 121 47 32 ''' pandas中None与np.nan的操作: 1) 判断函数: (1).df.isnull()与 pd.isnull() 同样的效果 # 作用:判断DataFrame中的每个元素是否为NAN, 是返回True, 否则返回False ''' 语文 数学 英语 python 张三 False True False False 李四 False False True False 王五 False False False False ''' (2).df.notnull()与pd.notnull()同样的效果 # 作用:判断DataFrame中的每个元素是否不为NAN, 是返回True, 否则返回False ''' 语文 数学 英语 python 张三 True False True True 李四 True True False True 王五 True True True True ''' (3) # 接和any和all, 判断行列是否有空数据. # 判断列是否有空数据 df.isnull().any(axis=0) df.isnull().any(axis=1) 2).过滤函数: df = DataFrame({'语文': np.random.randint(0,150, size=3), '数学': np.random.randint(0,150, size=3), '英语': np.random.randint(0,150, size=3), 'python': np.random.randint(0,150, size=3)}, index = ['张三', '李四', '王五']) df.loc['张三', '数学'] = np.nan df.loc['李四', '英语'] = None ''' 语文 数学 英语 python 张三 20 NAN 79 142 李四 103 16 NAN 110 王五 95 121 47 32 ''' df.dropna(axis=0, how='any', subset=None, inplace=False) # 用于删除含有空值的行或列 # axis控制删除行还是列, axis=0表示删除行, # how控制怎么删, any表示只要有空删除. all全是空才删除. 默认any # subset 指定列索引子集,只判断子集的元素 # inplace 是否改变原DataFrame, 默认不改变 事例: (1) df.dropna(axis=0) ''' 语文 数学 英语 python 王五 147 40.0 95.0 41 ''' (2) df.dropna(axis=0, how='all', subset=['数学']) ''' 语文 数学 英语 python 李四 87 5.0 NaN 38 王五 147 40.0 95.0 4 ''' 3).填充函数 df.fillna() df = DataFrame({'语文': np.random.randint(0,150, size=3), '数学': np.random.randint(0,150, size=3), '英语': np.random.randint(0,150, size=3), 'python': np.random.randint(0,150, size=3)}, index = ['张三', '李四', '王五']) df.loc['张三', '数学'] = np.nan df.loc['李四', '英语'] = None ''' 语文 数学 英语 python 张三 20 NAN 79 142 李四 103 16 NAN 110 王五 95 121 47 32 ''' # 用指定的值指定的方式填充NAN df.fillna(value=None, method=None, axis=None, inplace=False, limit=None) # fillna有两个用法. # 第一个用法: 用指定的值来填充. (1) df.fillna(value=88) ''' 语文 数学 英语 python 张三 20 88 79 142 李四 103 16 88 110 王五 95 121 47 32 ''' # 第二个用法, 用已有的值填充. # method : {'backfill', 'bfill', 'pad', 'ffill', None} # backfill bfill -- 用后面的数据填充 # pad, ffill -- 用前面的数据填充 forward # 前后关系要根据axis来定 # limit 限制连续填充的次数 df.fillna(axis=1, method='ffill')
''' 1.创建多层索引的DataFrame的方式 隐式、显示 ''' # 1). 给索引index和columns参数传递两个或更多的数组 index = [['一班','一班','一班','二班','二班','二班',], ['张三','李四','王五','赵六','田七','黄八']] columns = [['期中','期中','期中','期末','期末','期末'],['语文', '数学', '英语','语文', '数学', '英语']] data = np.random.randint(0, 100, size=(6, 6)) df = DataFrame(index=index, columns=columns, data=data) display(df) # 2). 显示构造之数组pd.MultiIndex.from_arrays() index = pd.MultiIndex.from_arrays([['一班','一班', '二班','二班'],['张三','李四','王五','赵六']]) columns= pd.MultiIndex.from_arrays([['期中','期中','期末','期末'],['语文', '数学','语文', '数学']]) data = np.random.randint(0, 100, size=(4, 4)) df2 = DataFrame(index=index, columns=columns, data=data) display(df2) # 3). 显示构造之元组pd.MultiIndex.from_arrays() index = pd.MultiIndex.from_tuples([('一班', '张三'),('一班', '李四'),('二班', '王五'),('二班', '赵六')]) columns= pd.MultiIndex.from_tuples([('期中','语文'),('期中','数学'),('期末','语文'),('期末','数学')]) data = np.random.randint(0, 100, size=(4, 4)) df3 = DataFrame(index=index, columns=columns, data=data) display(df3) # 4).显示构造之元组pd.MultiIndex.from_product() index = pd.MultiIndex.from_product([['一班', '二班'], ['张三', '李四', '王五']]) columns = pd.MultiIndex.from_product([['期中', '期末'], ['语文', '数学', '英语']]) data = np.random.randint(0, 150, size=(6,6)) df = DataFrame(index=index, columns=columns, data=data) display(df) ''' 2.多层索引对象的索引 ''' index = pd.MultiIndex.from_tuples([('一班', '张三'),('一班', '李四'),('二班', '王五'),('二班', '赵六')]) columns= pd.MultiIndex.from_tuples([('期中','语文'),('期中','数学'),('期末','语文'),('期末','数学')]) data = np.random.randint(0, 100, size=(4, 4)) df3 = DataFrame(index=index, columns=columns, data=data) display(df3) ''' 期中 期末 语文 数学 语文 数学 一班 张三 94 21 74 9 李四 57 53 9 18 二班 王五 80 99 12 26 赵六 56 60 48 75 ''' # (1)列索引 df['期中', '语文'] # 不推荐 display(df3.loc[:, ('期中', '语文')]) # 列显式索引 display(type(df3.loc[:, ('期中', '语文')])) # 返回Series display(df3.iloc[:, [0]]) # 列隐式索引, 隐式索引只有一层 # (2)行索引 display(df3.loc[[('二班','赵六')]]) # 行显式索引, 加多一层[]返回dataframe display(df3.iloc[[1]]) # # 行隐式索引, 加多一层[]返回dataframe # (3)元素索引 display(df3.loc[('二班','王五'),('期末','语文')]) # 显式索引元素 df3.iloc[2, 2] # 隐式索引元素 df3.iloc[[2], [2]] ''' 3.多层索引对象切片操作 ''' # (1)列切片 display(df3.loc[:, '期中':'期中']) # 列显式切片 , 不能再加小括号,列显式切片只能切一层 display(df3.loc[:, [('期中','语文')]]) display(df3.iloc[:, 0:1]) # 列隐式索引, 隐式索引只有一层 # (2)行切片 display(df3.loc['二班':'二班']) # 行显式切片, 不能再加小括号,行显式切片只能切一层 display(df3.iloc[2:]) # 行隐式切片, ''' 4. 多层索引对象索引的栈(stack) ''' # stack就是把列索引变成行索引. # unstack就是把行索引变成列索引 # df3.stack(level=-1, dropna=True) # level 用于指定索引,默认倒数第一层 df3.stack() # df3.unstack(level=-1, fill_value=None) # fill_value用来填充空值的. df3.unstack(fill_value=0) ''' 5. 多层索引对象聚合操作 ''' # df3.sum(axis=None, skipna=None, level=None,) # 求和 # df3.mean(axis=None, skipna=None, level=None,) # 求平均 # df3.std(axis=None, skipna=None, level=None,) # 求标准差 # axis=0 ,表示对行进行聚合, axis=1, 表示对列进行聚合. 默认对行聚合 # level指定要保留哪一层索引. display(df3.mean(level=0)) display(df3.sum(axis=1, level=0))
''' 1). 使用pd.concat()级联 ''' # 封装生成dataframe函数 def make_df(index, cols): df = DataFrame({col: [col + str(i) for i in index] for col in cols}) df.index = index return df df1 = make_df([1,2,3,4], list('ABCD')) df2 = df1.copy() display(df1, df2) # pd.concat(objs, axis=0, join='outer', # join_axes=None, ignore_index=False, # keys=None, levels=None, # names=None, verify_integrity=False, # sort=None, copy=True) # 1.axis来改变级联方向, axis=0 行级联,axis=1 列级联 默认行级联 # 2.join级联方式, # 外连接:补NaN(默认模式); # 内连接:只连接匹配的项; # 连接指定轴 join_axes # 2.ignore_index 忽略原有的索引,用0,1,2...重新编码 # 3.verify_integrity 索引是否能重复,默认值为False, # 如果为True当创建相同的index时会抛出ValueError的异常 # 4.keys用于区分两个dataframe # 5.join_axes可以指定根据那个轴来对齐数据, 如果是index,要配合axis=1 display(pd.concat((df1, df2), axis=0)) display(pd.concat((df1, df2), axis=1)) display(pd.concat((df1, df2), axis=1, ignore_index=True)) # ignore_index 忽略原有的索引,用0,1,2...重新编码 # display(pd.concat((df1, df2), verify_integrity=True)) pd.concat([df1,df2],axis=1, join_axes=[df2.index]) ''' 2).不匹配级联 不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致 有4种连接方式: 外连接:补NaN(默认模式) 内连接:只连接匹配的项 左连接: 右边可能出现NaN 右连接: 左边可能出现NaN ''' df1 = make_df([1,2,3,4], list('ABCD')) df2 = make_df([2,3,4,5], list('BCDE')) # 只输出匹配的数据 pd.concat((df1, df2), axis=1, sort=True, join='inner') 连接指定轴 join_axes # 左连接 pd.concat((df1, df2), axis=1, sort=True, join_axes=[df1.index]) # 右连接 pd.concat((df1, df2), axis=1, sort=True, join_axes=[df2.index]) ''' 3) 使用append()函数添加 有一个函数append专门用于在后面添加 df1.append(other, ignore_index=False, verify_integrity=False, sort=None) ''' # concat是pd的方法, append是对象的方法 df1.append(df2, sort=True, verify_integrity=False)
df1 = DataFrame({'name':['张三','李四','Chales'],'id':[1,2,3],'age':[22,21,25]}) df2 = DataFrame({'sex':['男','男','女'],'id':[2,3,4],'group':['sale','search','service']}) display(df1, df2) pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y')) # how 默认内连接, 两张表的某列值相等才会筛选出来 # 合并的时候,默认使用内合并 1、第一张表某列索引columns与第二张表的某列索引columns 只有一个列名称相同 1) 一对一合并 pd.merge(df1, df2) 2) 多对一合并 pd.merge(df1, df2) 3) 多对多合并 pd.merge(df1, df2) 2、第一张表某列索引columns与第二张表的某列索引columns 不止一个列名称相同 使用on=显式指定哪一列为key, 然后再进行合并,当有多个key相同时使用 其他索引会加上suffixes=('_x', '_y')进行区别 df1.merge(df2, on='name') 3、第一张表某列索引columns与第二张表的某列索引columns列名称不相同,但某列与某列数据的属性一致 使用left_on和right_on指定左右两边的列作为key,当左右两边的key都不相等时使用 # 没有列名相同,但是有数据相同,也可以合并 pd.merge(df1, df2, left_on='name', right_on='名字') # 明确的指定了要合并的列之后,可以left_index来指定要保留的行索引. pd.merge(ddd, ddd4, left_on='张三', right_on='张十三', left_index=True) 4、当左边的列和右边的index相同的时候,使用right_index=True # 指定列和索引进行合并 pd.merge(df1, df2, left_on='age', right_index=True) # 合并的时候,默认使用内合并 pd.merge(df1, df2, left_on='name', right_on='名字', how='inner') # 外合并 pd.merge(ddd, ddd4, left_on='张三', right_on='张十三', how='outer') # 补NaN # 左合并 pd.merge(df1, df2, left_on='name', right_on='名字', how='left') # 左边的表记录全要,左边的记录与右边没有匹配的,右边补NaN # 右合并 pd.merge(df1, df2, left_on='name', right_on='名字', how='right') # 右边的表记录全要,右边的记录与左边没有匹配的,左边补NaN 当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名 pd.merge(df1, df2, on='name', suffixes=['_df1', '_df2'])
''' 1、检测、删除重复行 使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象, 每个元素对应一行,如果该行不是第一次出现,则元素为True df.duplicated(subset=None, keep='first') 参数subset: 指定子集中的行是否重复 参数keep: 从头还是从未开始比较 -- first/last ''' df = make_df([1,2,3,4], list('ABCD')) df.loc[1] = df.loc[2] # 使之存在重复行 df display(df.duplicated(keep='last', subset=['A', 'B', 'C'])) ''' 使用drop_duplicates()函数删除重复的行 df.drop_duplicates(subset=None, keep='first', inplace=False) 参数subset: 指定子集中的行是否重复 参数keep: 从头还是从未开始比较 参数inplace: 是否改变原DataFrame np.logical_and() # 与 np.logical_or() # 或 np.logical_not() # 非 ''' df.drop_duplicates(subset=['A', 'B', 'C'], keep='last') # 第二种方式,传入series,取反,为True才显示 df[~df.duplicated(keep='last', subset=['A', 'B', 'C'])] df[np.logical_not(df.duplicated(keep='last', subset=['A', 'B', 'C']))] ''' 2、数据替换 replace()函数:替换元素 ''' mapping = {'原dataframe数据':'要替换的数据'} mapping = {4: 104, 23: 123, 16: 116, 54: 105, 45: 104, 25: 125} ddd.replace(mapping) mapping = {np.nan: 0} # 替换NaN ddd.replace(mapping) ''' 3.数据新增/修改 使用map()函数,由已有的列生成一个新列 适合处理某一单独的列 ''' # 使用数学这一列的成绩新建一列computer mapping = {126: 106, 66: 96, 138: 108,} ddd['computer'] = ddd['数学'].map(mapping) # 修改已有列 mapping = {0: 100, 71: 117, 110: 110, 83: 103} ddd['python'] = ddd['python'].map(mapping) # map()函数中可以使用lambda函数 ddd['语文'] = ddd['语文'].map(lambda score: score + 20) ddd # map()函数中可以使用函数 def convert(score): if score >= 120: return '优秀' elif score >= 90: return '及格' else: return '不及格' ddd['语文_score'] = ddd['语文'].map(convert) ''' 4.索引替换 rename() ''' mapping = {'张三': 'Mr Zhang', '李四': 'Mr Lee', '王五': 'Lao Wang', '赵六': 'Mr Six'} ddd.rename(mapping, axis=0)
''' 1.使用describe()函数查看每一列的描述性统计量 含每一列的count、mean、std、min、max等等 ''' ddd.describe() ''' 2.异常值的检测和过滤不是特定的函数, 这是一套方法论. 1) 定义异常值的标准. 2) 将这个标准,写成条件. 3) 根据条件,取反, 把异常值过滤掉. ''' 例如:新建一个形状为10000*3的标准正态分布的DataFrame(np.random.randn), 去除掉所有满足以下情况的行:其中任一元素绝对值大于3倍标准差 df = DataFrame(data=np.random.randn(10000, 3)) df.head() # 异常值的标准 df.std() # 条件 cond = (df.abs() > 3* df.std()).any(axis=1) # 根据条件,取反, 把异常值过滤掉 df[~cond] ''' 3. 抽样 # 抽样分成两种, 有放回抽样. 无放回抽样. 有放回抽样: 样本可以重复 无放回抽样:样本不可以重复 ''' 有放回抽样: take和np.random.randint()结合实现有放回抽样. df.take(np.random.randint(0, 4, size=4)) 无返回抽样: take和np.random.permutation([0,1,2,3])结合实现有无返回抽样 --排列组合 df.take(np.random.permutation([0,1,2,3])) # 1,2,3,4 ''' 4.数据聚合 数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。 数据分类处理: 分组:先把数据分为几组 用函数处理:为不同组的数据应用不同的函数以转换数据 合并:把不同组得到的结果合并起来 数据分类处理的核心: groupby()函数 ''' # 分组 df = DataFrame({'color':['red','white','red','cyan','cyan','green','white','cyan'], 'price':np.random.randint(0,8,size = 8), 'weight':np.random.randint(50,55,size = 8)}) df.groupby(by='color') 使用.groups属性查看各行的分组情况: df.groupby(by='color').groups # 聚合 df.groupby(by='color').sum() # 会计算所有的列 price_sum = df.groupby(by='color')[['price']].sum() # 推荐写法. 只会计算指定的列. # 合并 pd.merge(df, price_sum, left_on='color', right_index=True, suffixes=['', '_sum']) ''' 可以使用pd.merge()函数将聚合操作的计算结果添加到df的每一行 使用groupby分组后调用加和等函数进行运算,然后最后可以调用add_prefix(),来修改列名 ''' price_mean.add_prefix('mean_') # 给列添加前缀 price_mean.add_suffix('_mean') # 给列添加后缀
import pandas as pd from pandas import Series,DataFrame import numpy as np ''' 1.read_csv()从使用指定分隔符的文件中读取数据形成DataFrame 常用参数: sep:指定文件内容分隔符 index_col: 指定行索引,如果读取的文件中有 header: 默认以读取文件的第一行为列索引,指定为None时,以0,1...设置 2.read_table() 默认参数: sep='\t' ''' pd.read_csv('./data/SMSSpamCollection', sep='\t', header=None) # 指定制表符 => '\t' pd.read_csv('./type-.txt', sep='-', header=None) pd.read_table('./data/SMSSpamCollection', header=None) # 分隔符是制表符. ''' 3.pd.read_excel() # 读取excel表格 sheet_name指定读哪一个sheet页, index_col指定行索引用的列, header指定列索引用哪几行. ''' pd.read_excel('./123.xlsx', sheet_name=2, index_col=[0,1], header=[0,1]) ''' 4.sqlite数据库读取 pd.read_sql() # 从数据库读取数据形成DataFrame dataFrame.to_csv() # 将dataFrame写成csv格式 dataFrame.to_json() # 将dataFrame写成json格式 dataFrame.to_html() # 将dataFrame写成html=>table格式 dataFrame.to_sql() # 将dataFrame写到sqlite数据库中, ''' # 创建sqlite的连接 import sqlite3 conn = sqlite3.connect('./data.sqlite') weather_2017 = pd.read_sql('select * from Weather_2017 limit 30', conn, index_col='index') weather_2017.to_csv('./weather_2017.csv') # 将dataFrame写成csv格式 weather_2017.to_json('./weather_2017.json') # 将dataFrame写成json格式 weather_2017.to_html('./weather_2017.html') # 将dataFrame写成html=>table格式 ''' # 将dataFrame写到sqlite数据库中, 参数:表名, conn: 连接对象, if_exists: 表存在则追加 ''' weather_2017.to_sql('Weather_2019', conn, if_exists='append') ''' 5.### 从mysql中读取数据 ''' !pip install pymysql conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='root', database='blog', charset='utf8') item_dataframe = pd.read_sql('select * from qiushi limit 30', conn) # 从数据库中读取数据形成DataFrame # 将DataFrame 写入数据库 !pip install sqlalchemy from sqlalchemy.engine import create_engine engine = create_engine('mysql+pymysql://root:root@localhost/qiubai?charset=utf8') weather_2017.to_sql('Weather_2019', engine) # 将DataFrame写入到数据库中,=> 一参:表名 二参:数据引擎 -- 对于关系型数据库 # 根据url获取网络上的数据 pd.read_csv('https://raw.githubusercontent.com/datasets/investor-flow-of-funds-us/master/data/weekly.csv')
一、线形图:想看走势就画线形图 1.Series线形图 # 以index作为x轴数据,以value作为y轴数据 s = Series(data=np.random.randint(0, 10, size=10)) s.plot() 2.DataFrame线形图 # 以行索引作为x轴数据,y轴的取值范围取决于data的范围, 每一列就是一条线. index = [0, 1 , 2, 3] columns = ['语文', '数学', '英语', 'python'] data = np.random.randint(0, 150, size=(4,4)) df = DataFrame(index=index, columns=columns, data=data) # 改中文字体. plt.rcParams['font.sans-serif'] = ['SimHei'] # 修复中文字体下负号不能正常显示的问题. plt.rcParams['axes.unicode_minus'] = False df.plot() 二、柱状图:比较大小的时候画柱状图 1.Series柱状图 # 以index作为x轴数据,以value作为y轴数据 s = Series(data=np.random.randint(0, 10, size=10)) s.plot(kind='bar') # 垂直柱状图 s.plot(kind='barh') # 水平柱状图 2、DataFrame柱状图 # 以index索引为X轴, columns每一项都是一个柱形 index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语', 'python'] data = np.random.randint(0, 150, size=(4,4)) df = DataFrame(index=index, columns=columns, data=data) # 改中文字体. plt.rcParams['font.sans-serif'] = ['SimHei'] # 修复中文字体下负号不能正常显示的问题. plt.rcParams['axes.unicode_minus'] = False df.plot(kind='bar') # 垂直柱状图 df.plot(kind='barh') # 水平柱状图 三、直方图: 直方图的Y轴数据是数据出现的次数(频数) 直方图反映数据的分布情况 柱高表示数据的频数,柱宽表示各组数据的组距 参数bins可以设置直方图方柱的个数上限,越大柱宽越小,数据分组越细致 设置normed参数为True,可以把频数转换为概率 data = np.random.randint(0, 10, size=10) s = Series(data) s.plot(kind='hist', bins=10) # y轴是各个数字出现的次数(频数), bins组距 s.plot(kind='hist', bins=10, density=True) # density=True, y轴的值是概率密度. # 计算直方数据 # np.histogram(a, bins=10, range=None,) # 参数range 默认取值a的(a.min(), a.max()) # bins默认为10,会把range区间分为10份来确定每个柱子的x轴区间 np.histogram(s) # 2. 到 2.7之间出现1次, 2.7-3.4出现1次 (array([1, 1, 0, 0, 1, 1, 0, 2, 2, 2], dtype=int64), array([2. , 2.7, 3.4, 4.1, 4.8, 5.5, 6.2, 6.9, 7.6, 8.3, 9. ])) kde图:核密度估计,用于弥补直方图由于参数bins设置的不合理导致的精度缺失问题 s.plot(kind='hist', bins=10, density=True) s.plot(kind='kde') 四、散点图: 散布图是观察两个一维数据数列之间的关系的有效方法,DataFrame对象可用 df = DataFrame({'A': np.random.randn(1000), 'B':np.random.randn(1000), 'C': np.random.randn(1000), 'D': np.random.randn(1000)}) df.plot(x='A', y='B', kind='scatter', alpha=0.5) 散布图矩阵,当有多个点时,两两点的关系 使用函数:pd.plotting.scatter_matrix(), 参数diagonal:设置对角线的图像类型 # 散点图矩阵: 可以 用来观察两两之间 _ = pd.plotting.scatter_matrix(df, figsize=(4*4, 4*4), diagonal='kde')
# 1.列出目录下的一类文件 # 方式一 df = DataFrame() for file in os.listdir(): if file.endswith('csv'): temp = pd.read_csv(file) df = df.append(temp) # 方式二 [file for file in os.listdir() if re.match('[a-z]+_\d{6}\.csv', file)] # 方式三 import glob glob.glob('./*.csv') #相当于 ls *.csv # 方式四 import os for i in os.walk('./'): # 生成器,当前目录下的所有目录和文件 print(i) print('--------------') # 2.将ndarray降为一维: nd = np.random.randint(0, 100, size=(3, 4, 5)) nd.ravel() # 3. n.reshape(-1, 1) n = np.random.randint(0, 10, size=(3, 4)) n.reshape(-1, 1) # 首先n.reshape(-1) 是把ndarray变为一维, # 然后n.reshape(-1, 1) 是把ndarray变成一列 也就是说,先前我们不知道z的shape属性是多少,但是想让z变成只有一列, 行数不知道多少,通过z.reshape(-1,1) # 4. 将相关列转换为索引值 columns = [ 'education', 'marital_status', 'occupation', 'race', 'sex', 'native_country'] for col in columns: uni = data[col].unique() def convert(item): index = np.argwhere(uni == item)[0,0] return index data[col] = data[col].map(convert)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。