2.pandas的使用
一、pandas简介
pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
Pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)
二、Series(序列)使用
1.创建Series
from pandas import Series
import numpy as np
s = Series(data = [94, 54, 80])
print(type(s))
s = Series(data = [94, 54, 80], index=['语文','数学', '英语'])
print(s)
'''
语文 94
数学 54
英语 80
dtype: int64
'''
nd = np.random.randint(1, 10, size=5)
s = Series(data=nd)
print(s)
s = Series({'语文':90, '数学':88, '英语':89})
print(s)
print(s.index)
使用列表、字典与ndarray创建的区别:
由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(字典、列表没有这种情况)
2.Series的属性
from pandas import Series
s = Series({'语文':88, '数学':89, '英语':90})
print(s.index)
print(s.values, type(s.values))
print(s.shape)
print(s.size)
3.Series的索引和切片
from pandas import Series
s = Series({'语文':88, '数学':89, '英语':90})
print(s['英语'],)
print(s.loc['语文'])
print(s[0])
print(s.iloc[1])
s.get('语文')
s.get('语文1')
print(type(s.loc[['语文']]))
print('\n******切片******\n')
print(s['语文':'数学'])
print(s.loc['语文':'数学'])
print('**********')
print(s[0:2])
print(s.iloc[0:2])
4.Series 常用方法
import pandas as pd
from pandas import Series
s = Series({'语文':88, '数学':89, '英语':90})
print(s.head(2))
print(s.tail(2))
s = Series({'语文':88, '数学':89, '英语':90, '体育':None})
pd.isnull(s)
s.isnull()
pd.notnull(s)
s.notnull()
'''
语文 False
数学 False
英语 False
体育 True
dtype: bool
'''
5.Series 增加删除修改元素
s = Series({'语文':88, '数学':89, '英语':90})
s.loc['语文'] = 90
a = s.pop('英语')
print(a)
s = s.append(Series({'py':80}))
print(s)
6.Series的运算
s = Series({'语文':'88', '数学':'89', '英语':'90'})
s+'1'
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)
'''
py 92.0
数学 178.0
英语 92.0
语文 176.0
dtype: float64
'''
三、DataFrame使用
1.创建DataFrame
from pandas import DataFrame
import numpy as np
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语']
data = np.random.randint(0, 150, size=(4,3,))
df = DataFrame(data=data, index=index, columns=columns)
print(df, type(df))
'''
语文 数学 英语
张三 119 97 25
李四 72 65 52
王五 112 87 101
赵六 142 85 133
<class 'pandas.core.frame.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, type(df))
'''
语文 数学 英语 python
张三 6 13 121 3
李四 0 73 36 109
王五 127 135 4 7
赵六 94 126 146 139
<class 'pandas.core.frame.DataFrame'>
'''
2.1.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)
print(df.columns)
print(df.values)
'''
[[ 6 20 113 89]
[ 46 25 11 133]
[ 12 74 123 55]
[ 0 142 121 62]]
'''
print(df.shape)
2.2.DataFrame的增删改
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
data = df[['英语']].copy()
data['英语'] = data['英语'] + 1
df
3.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['语文']))
'''
张三 42
李四 44
王五 23
赵六 13
Name: 语文, dtype: int32
<class 'pandas.core.series.Series'>
'''
print(df[['语文', '数学']], type(df[['语文']]))
'''
语文 数学
张三 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['张三'])
print(df['语文']['张三'])
print(df.loc['王五'].loc['数学'])
print(df.loc['王五']['数学'])
print(df.loc['王五', '数学'])
display(df.loc[['张三'], ['数学']])
4.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['张三':'李四'])
'''
语文 数学 英语 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]
5.DataFrame的运算
(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
如果要保留原始数据则使用add()、sub()、mul()、div() --加减乘除
df.add(df2, 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')
总结: DataFrame和Series进行运算的时候,默认是按照DataFrame的列索引进行操作,
列索引一致才进行运算,列索引不一致补NaN.
可以通过pandas封装的运算函数的axis来修改操作的方向.
6.DataFrame处理丢失数据
(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() 同样的效果
'''
语文 数学 英语 python
张三 False True False False
李四 False False True False
王五 False False False False
'''
(2).df.notnull()与pd.notnull()同样的效果
'''
语文 数学 英语 python
张三 True False True True
李四 True True False True
王五 True True True True
'''
(3)
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)
事例:
(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
'''
df.fillna(value=None, method=None, axis=None, inplace=False, limit=None)
(1) df.fillna(value=88)
'''
语文 数学 英语 python
张三 20 88 79 142
李四 103 16 88 110
王五 95 121 47 32
'''
df.fillna(axis=1, method='ffill')
7.DataFrame多层索引
'''
1.创建多层索引的DataFrame的方式
隐式、显示
'''
index = [['一班','一班','一班','二班','二班','二班',], ['张三','李四','王五','赵六','田七','黄八']]
columns = [['期中','期中','期中','期末','期末','期末'],['语文', '数学', '英语','语文', '数学', '英语']]
data = np.random.randint(0, 100, size=(6, 6))
df = DataFrame(index=index, columns=columns, data=data)
display(df)
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)
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)
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
'''
df['期中', '语文']
display(df3.loc[:, ('期中', '语文')])
display(type(df3.loc[:, ('期中', '语文')]))
display(df3.iloc[:, [0]])
display(df3.loc[[('二班','赵六')]])
display(df3.iloc[[1]])
display(df3.loc[('二班','王五'),('期末','语文')])
df3.iloc[2, 2]
df3.iloc[[2], [2]]
'''
3.多层索引对象切片操作
'''
display(df3.loc[:, '期中':'期中'])
display(df3.loc[:, [('期中','语文')]])
display(df3.iloc[:, 0:1])
display(df3.loc['二班':'二班'])
display(df3.iloc[2:])
'''
4. 多层索引对象索引的栈(stack)
'''
df3.stack()
df3.unstack(fill_value=0)
'''
5. 多层索引对象聚合操作
'''
display(df3.mean(level=0))
display(df3.sum(axis=1, level=0))
8.1.DataFrame的级联
'''
1). 使用pd.concat()级联
'''
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)
display(pd.concat((df1, df2), axis=0))
display(pd.concat((df1, df2), axis=1))
display(pd.concat((df1, df2), axis=1, ignore_index=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)
'''
df1.append(df2, sort=True, verify_integrity=False)
8.1.DataFrame的合并
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'))
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='名字')
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')
pd.merge(df1, df2, left_on='name', right_on='名字', how='left')
pd.merge(df1, df2, left_on='name', right_on='名字', how='right')
当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名
pd.merge(df1, df2, on='name', suffixes=['_df1', '_df2'])
9.数据重复处理、数据替换replace、数据新增map、索引替换
'''
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')
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}
ddd.replace(mapping)
'''
3.数据新增/修改
使用map()函数,由已有的列生成一个新列
适合处理某一单独的列
'''
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)
ddd['语文'] = ddd['语文'].map(lambda score: score + 20)
ddd
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)
10.异常值检测和过滤、抽样、 数据聚合
'''
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]))
'''
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')
11.pandas数据加载
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)
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数据库中,
'''
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')
weather_2017.to_json('./weather_2017.json')
weather_2017.to_html('./weather_2017.html')
'''
# 将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)
!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)
pd.read_csv('https://raw.githubusercontent.com/datasets/investor-flow-of-funds-us/master/data/weekly.csv')
12.Series与DataFrame简单画图
一、线形图:想看走势就画线形图
1.Series线形图
s = Series(data=np.random.randint(0, 10, size=10))
s.plot()
2.DataFrame线形图
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柱状图
s = Series(data=np.random.randint(0, 10, size=10))
s.plot(kind='bar')
s.plot(kind='barh')
2、DataFrame柱状图
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)
s.plot(kind='hist', bins=10, density=True)
np.histogram(s)
(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')
13.常用奇葩方式与函数
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')
import os
for i in os.walk('./'):
print(i)
print('--------------')
nd = np.random.randint(0, 100, size=(3, 4, 5))
nd.ravel()
n = np.random.randint(0, 10, size=(3, 4))
n.reshape(-1, 1)
也就是说,先前我们不知道z的shape属性是多少,但是想让z变成只有一列,
行数不知道多少,通过z.reshape(-1,1)
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)