前言:python数据挖掘pandas的基础知识,简单总结,主要是为了方便自己写的时候查看,发现有用的方法,随时补充,欢迎指正
数据挖掘专栏
pandas基础
一、认识pandas
Pandas是一个强大的分析结构化数据的工具集,它的使用基础是Numpy(提供高性能的矩阵运算),用于数据挖掘和数据分析,同时也提供数据清洗功能。pandas是我最喜欢用的库!,不管用python做什么,都会先写上import pandas as pd
二、两种重要的数据类型
1、序列(Series)
Series是一维数组,与Numpy中的一维array类似。两者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率,并且series可以运用Ndarray或字典的几乎所有索引操作和函数,融合了字典和ndarray的优点。(来源知乎链接)
(1)Series的创建
index: 它是从NumPy数组继承的Index对象,保存标签信息。
values: 保存值的NumPy数组。
- 直接创建
In[2]: import pandas as pd
In[3]: s = pd.Series([1,2,3,4,5])
In[4]: s
Out[4]:
0 1
1 2
2 3
3 4
4 5
dtype: int64
- 通过array创建
In[8]: a = np.array([1,2,3,4,5])
In[9]: pd.Series(a)
Out[9]:
0 1
1 2
2 3
3 4
4 5
dtype: int32
- 通过列表创建
In[24]: L = [1,2,5]
In[25]: pd.Series(L)
Out[25]:
0 1
1 2
2 5
dtype: int64
- 通过字典创建
In[10]: dict = {'a':1,'b':2,'c':3}
In[11]: pd.Series(dict)
Out[11]:
a 1
b 2
c 3
dtype: int64
(2)Series的索引
- 使用index进行索引
In[6]: s[1:3]
Out[6]:
1 2
2 3
dtype: int64
In[48]: s['a':'c']
Out[48]:
a 1
b 2
c 3
dtype: int64
- 条件索引
In[19]: dict = {'a':1,'b':2,'c':3}
In[20]: s = pd.Series(dict)
In[21]: s[s>1]
Out[21]:
b 2
c 3
dtype: int64
2、数据框(DataFrame)
(1)DataFrame的创建
- 直接创建
In[30]: pd.DataFrame([['a','b'],[1,2]])
Out[30]:
0 1
0 a b
1 1 2
- 通过二维array创建
In[28]: a = np.array([['张三','23'],['李四','25']])
In[29]: pd.DataFrame(a)
Out[29]:
0 1
0 张三 23
1 李四 25
- 通过字典创建
In[26]: df = pd.DataFrame({'name':['t','r','y'],'age':['1','2','3']})
In[27]: df
Out[27]:
name age
0 t 1
1 r 2
2 y 3
(2)DataFrame的索引和切片
- df[[‘name1’,‘name2’]](一定要是列表的形式)
In[12]: df = df[['review_date','customer_id']]
In[13]: df.head(1)
Out[13]:
review_date customer_id
0 2008-01-01 13273034
- loc()
切片时包括左右端点,列要按列名列表切片
In[82]: df
Out[82]:
name age
0 t 1
1 r 2
2 y 3
In[83]: df.loc[1:2,['name','age']]
Out[83]:
name age
1 r 2
2 y 3
- iloc()
切片时包括左右端点,列要按列数列表切片
In[94]: df.iloc[1:2,[0,1]]
Out[94]:
name age
1 r 2
- 条件索引
In[95]: df[df['age']>=2]
Out[95]:
name age
1 r 2
2 y 3
- where()
注意与条件索引的区别(NaN)
In[96]: df.where(df['age']>=2)
Out[96]:
name age
0 NaN NaN
1 r 2.0
2 y 3.0
三、pandas的常用方法
DataFrame提取一列就是Series,所有要对DataFrame的某一列进行分析时可以用Series的方法。(个人看法)
1、Series的常用方法
方法 | 作用 |
---|---|
Ser.mean() | 均值 |
Ser.median() | 中位数 |
Ser.sum() | 求和 |
Ser.cumsum() | 求累加序列 |
Ser.std() | 标准差 |
Ser.var() | 方差 |
Ser.mode() | 众数 |
Ser.value_counts() | 每个值的数量,sort=Ture/False(是否排序) |
Ser = Ser.astype(int) | 改变数据类型 |
Ser.sort_values() | 按val排序,ascending=False降序 |
Ser.sort_index() | 按index排序,ascending=False降序 |
2、DataFrame的常用方法
方法 | 作用 |
---|---|
df.head(n) | 输出df前n行 |
df.shape | 返回行列数 |
df.dtypes | 返回每列的数据类型 |
df.info() | 快速查看数据的描述 |
df.drop([‘name1’,‘name2’],axis=1) | 删除name1和name2列 |
df.values() | 转为二维array |
df.columns | 列名组成的列表 |
df = df.reset_index(drop=True) | 设为默认索引,drop是否保留原来的index |
df = df.set_index(‘name’) | 将‘name’列设为index |
df.replace(‘str1’,‘str2’) | df中str2替换str2 |
df.count() | 非NaN的数量 |
df.max()、df.min()、df.mean() | 返回最大值、最小值、均值 |
df.median() | 返回中位数 |
df.mode() | 众数 |
df.describe() | 输出数值型数据的统计描述 |
Ser1.cov(Ser2) | 相关系数和协方差 |
四、数据分析
1、数据处理
(1)重复值处理
- df.duplicated().any():T表示有,检测是否有重复值
In[69]: df.duplicated()
Out[69]:
0 False
1 True
dtype: bool
- df.drop_duplicates():删除重复项
In[70]: df.drop_duplicates()
Out[70]:
a b
0 1 1
(2)缺失值处理
- df.isnull().any():T表示有,检测是否有缺失值
In[114]: df.isnull().any()
Out[114]:
a False
b True
dtype: bool
- df.dropna():删除有缺失值的行
In[115]: df.dropna()
Out[115]:
a b
0 1 1.0
2 3 4.0
3 1 1.0
- 缺失值替换
df.fillna(method=‘ffill’):前向替换
df.fillna(method=‘bfill’):后向替换
df.fillna(value=0):常数替换/统计值替换
In[117]: df.fillna(method='ffill')
Out[117]:
a b
0 1 1.0
1 2 1.0
2 3 4.0
3 1 1.0
In[118]: df.fillna(method='bfill')
Out[118]:
a b
0 1 1.0
1 2 4.0
2 3 4.0
3 1 1.0
In[119]: df.fillna(value=0)
Out[119]:
a b
0 1 1.0
1 2 0.0
2 3 4.0
3 1 1.0
2、数据的读取与写入
(1)读取
- pd.read_csv(‘filepath’,index_col=0,sep=’,’):读取csv文件,遇到有index的csv文件时,要加index_col=0
In[127]: df = pd.read_csv('hair_dryer_1_1_end.csv', index_col=0)
In[128]: df.head(1)
Out[128]:
customer_id review_id ... review_date helpful_polarity
0 43740490 r2xm83jye2kde2 ... 2002-03-02 -0.025203
[2 rows x 9 columns]
- pd.read_excel(‘filepath’,sheetname=[‘Sheet1’,‘Sheet2’])
In[135]: sheet = pd.read_excel('honor.xlsx',sheetname=['Sheet1','Sheet2'])
In[136]: sheet['Sheet1']
Out[136]:
队号 选题 ... 队员乙所在学校 队员丙所在学校
0 1385 B题 ... Hangzhou Dianzi University Hangzhou Dianzi University
[1 rows x 13 columns]
In[137]: sheet['Sheet2']
Out[137]:
队号 选题 评分
0 1385 B题 40
- pd.read_sql_query()
# 初始化数据库连接,使用pymysql模块
db_info = {'user': 'root',
'password': '123456',
'host': 'localhost',
'port': 3306,
'database': 'data1'
}
engine = create_engine('mysql+pymysql://%(user)s:%(password)s@%(host)s:%(port)d/%(database)s?charset=utf8' % db_info,
encoding='utf-8')
# 选择数据库
sql = "SELECT * FROM boston_house_prices"
df = pd.read_sql_query(sql=sql, con=engine)
(2)写入
- df.to_csv():df写入csv文件
In[7]: df.to_csv('data.csv')
- df.to_excel(‘filepath’,sheet_name=‘sheet’):写入xlsx文件
df.to_excel('data1.xlsx',sheet_name='Sheet1')
- df.to_sql(name=‘test’,con=engine,index=False):写入数据库
# write df to table 'test1'
df.to_sql(name='test1',
con=engine,
if_exists='append',
index=False
)
3、DataFrame的合并
(1)concat()函数
pd.concat()只是单纯的把两个表拼接在一起,参数axis是关键,它用于指定是行还是列,axis默认是0。当axis=0时,pd.concat([obj1, obj2])的效果与obj1.append(obj2)是相同的;当axis=1时,pd.concat([obj1, obj2], axis=1)的效果与pd.merge(obj1, obj2, left_index=True, right_index=True, how=‘outer’)是相同的。
- 参数介绍
1. objs:需要连接的对象集合,一般是列表或字典;
2. axis:连接轴向
3. ignore_index=True:重建索引
4. sort=False:是否排序
In[32]: df1 = pd.DataFrame(np.random.randn(2,3),columns=['a','b','c'])
In[33]: df2 = pd.DataFrame(np.random.randn(1,2),columns=['a','c'])
In[34]: pd.concat([df1,df2],ignore_index=True,sort=False)
Out[34]:
a b c
0 0.304922 1.077652 0.590005
1 1.452564 -1.691853 0.532386
2 1.210453 NaN 0.721812
(2)merge()函数
类似于关系型数据库的连接方式,可以根据一个或多个键将不同的df连接起来。该函数的典型应用场景是,针对同一个主键存在两张不同字段的表,根据主键整合到一张表里面。
- 参数介绍
- left和right:两个不同的DataFrame;
- how:连接方式,有inner(默认做inner连接(取key的交集))、left(以左表为主)、right(以右表为主)、outer(取key的并集)
- sort:默认为True,将合并的数据进行排序,设置为False可以提高性能;
In[55]: pd.merge(df1,df2)
Out[55]:
Empty DataFrame
Columns: [a, b, c]
Index: []
In[56]: pd.merge(df1,df2,how='outer')
Out[56]:
a b c
0 0.304922 1.077652 0.590005
1 1.452564 -1.691853 0.532386
2 1.210453 NaN 0.721812
In[57]: pd.merge(df1,df2,how='left')
Out[57]:
a b c
0 0.304922 1.077652 0.590005
1 1.452564 -1.691853 0.532386
In[58]: pd.merge(df1,df2,how='right')
Out[58]:
a b c
0 1.210453 NaN 0.721812
五、时间序列数据
1、将数据转换为时间序列
- pd.to_datetime():将数据类型转化为日期类型
In[20]: df.head(2)
Out[20]:
review_date customer_id
0 2008-01-01 13273034
1 2008-01-07 15162686
In[21]: df['review_date'] = pd.to_datetime(df['review_date'])
- df = df.set_index(‘date’):将日期作为index
df = df.set_index('review_date')
- df.sort_index():设置按日期排列顺序
In[34]: df.sort_index(ascending=True).head()
Out[34]:
customer_id
review_date
2008-01-01 13273034
2008-01-07 15162686
2008-01-08 22818581
2008-01-10 39916346
2008-01-11 21999521
2、按日期筛选数据
- 获取某年/某月的数据,某天的数据通过区间获得
In[39]: df['2008'].head(2)
Out[39]:
customer_id
review_date
2008-01-01 13273034
2008-01-07 15162686
In[40]: df['2008-02'].head(2)
Out[40]:
customer_id
review_date
2008-02-06 32710966
2008-02-10 50465122
In[47]: df['2008-02-10':'2008-02-11']
Out[47]:
customer_id
review_date
2008-02-10 50465122
- 获取时间段数据
In[47]: df['2008-02-10':'2008-02-11']
Out[47]:
customer_id
review_date
2008-02-10 50465122
In[55]: df['2013':].head(2)
Out[55]:
customer_id
review_date
2013-01-01 18533081
2013-01-01 34935781
3、按日期显示数据并统计
请注意:
- df.index 的数据类型是 DatetimeIndex;
- df_peirod 的数据类型是 PeriodIndex
- df.to_period(‘M’):按月显示,M、Q、A分别表示月季年
In[56]: df_period = df.to_period('M')
In[57]: df_period.head()
Out[57]:
customer_id
review_date
2008-01 13273034
2008-01 15162686
- df_period.index.asfreq(‘M’):按月频率显示
In[61]: df_period.index.asfreq('M')
Out[61]:
PeriodIndex(['2008-01', '2008-01', '2008-01', '2008-01', '2008-01', '2008-01',
'2008-01', '2008-01', '2008-01', '2008-01',
...
'2015-08', '2015-08', '2015-08', '2015-08', '2015-08', '2015-08',
'2015-08', '2015-08', '2015-08', '2015-08'],
dtype='period[M]', name='review_date', length=9568, freq='M')
- df.resample(‘M’).sum():按月统计求和(sum()、min()、max()、mean()、median()、mode())
In[68]: df.resample('w').sum().head(2)
Out[68]:
customer_id
review_date
2008-01-06 13273034
2008-01-13 182957057