前言
最近发现写的关于python的博客慢慢有人在看,并且关注。突然觉得分享学习内容供大家参考是一件快乐的事情,虽然跟其他大博主相差太远,文章质量也不在一个level。但是还是想在这里记录学习内容,一方面是提醒自己不断学习,不断更新;另一方面也想分享给同我一样的小白。每个大神背后都有一段慢慢成长的岁月。希望同大家一起进步~
缩写解释 & 库的导入
- df:任意的pandas DataFrame(数据框)对象
- s:任意的pandas Series(数组)对象
- pandas和numpy是用Python做数据分析最基础且最核心的库
import pandas as pd # 导入pandas库并简写为pd
import numpy as np # 导入numpy库并简写为np
数据的导入
- 数据导入时,路径需要加上引号
- pd.read_table(filename) # 导入有分隔符的文本 (如TSV) 中的数据
- pd.read_sql(query, connection_object) # 导入SQL数据表/数据库中的数据
- pd.read_json(json_string) # 导入JSON格式的字符,URL地址或者文件中的数据
- pd.read_html(url) # 导入经过解析的URL地址中包含的数据框 (DataFrame) 数据
- pd.read_clipboard() # 导入系统粘贴板里面的数据
- pd.DataFrame(dict) # 导入Python字典 (dict) 里面的数据,其中key是数据框的表头,value是数据框的内容。
import os
os.getcwd()#获取当前路径
pd.read_csv('测试数据.csv') # 在上述路径下,导入csv格式文件中的数据 ,注意要加引号
pd.read_excel('测试数据.xlsx') # 导入Excel格式文件中的数据
数据的导出
- df.to_csv(filename) # 将数据框 (DataFrame)中的数据导入csv格式的文件中
- df.to_excel(filename) # 将数据框 (DataFrame)中的数据导入Excel格式的文件中
- df.to_sql(table_name,connection_object) # 将数据框(DataFrame)中的数据导入SQL数据表/数据库中
- df.to_json(filename) # 将数据框(DataFrame)中的数据导入JSON格式的文件中
#创建一个df后导出到文件测试数据
df = pd.DataFrame(np.random.rand(10,5))
df.to_csv('测试数据.csv') # 将数据框 (DataFrame)中的数据导入csv格式的文件中
df.to_excel('测试数据.xlsx') # 将数据框 (DataFrame)中的数据导入Excel格式的文件中
创建测试对象
方式一
pd.DataFrame(np.random.rand(10,5)) # 创建一个5列10行的由随机浮点数组成的数据框 DataFrame
方式二
#pd.Series(my_list) # 从一个可迭代的对象 my_list 中创建一个数据组
my_list = ['Kesci',100,'欢迎来到科赛网']
pd.Series(my_list)
0 Kesci
1 100
2 欢迎来到科赛网
dtype: object
方式三
#df.index = pd.date_range('2017/1/1', periods=df.shape[0]) # 添加一个日期索引 index
#df.shape[0]首先将df的shape显示出来,在取df的行数
df = pd.DataFrame(np.random.rand(10,5))
df.index = pd.date_range('2017/1/1', periods=df.shape[0])
df
数据的查看与检查
- df.head(n):查看数据框的前n行
- df.tail(n):查看数据框的最后n行
- df.shape:查看数据框的行数与列数
- df.info():查看数据框 (DataFrame) 的索引、数据类型及内存信息
- df.describe(): 对于数据类型为数值型的列,查询其描述性统计的内容
- s.value_counts(dropna=False):查询每个独特数据值出现次数统计
- df.apply(pd.Series.value_counts):查询数据框 (Data Frame) 中每个列的独特数据值出现次数统计
#df.head(n) # 查看数据框的前n行
df = pd.DataFrame(np.random.rand(10,5))
df.head(3)
#df.tail(n) # 查看数据框的最后n行
df = pd.DataFrame(np.random.rand(10,5))
df.tail(3)
#df.shape # 查看数据框的行数与列数
df = pd.DataFrame(np.random.rand(10,5))
df.shape
- 输出结果
(10, 5)
#df.info() # 查看数据框 (DataFrame) 的索引、数据类型及内存信息
df = pd.DataFrame(np.random.rand(10,5))
df.info()
- 输出结果
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 0 10 non-null float64
1 1 10 non-null float64
2 2 10 non-null float64
3 3 10 non-null float64
4 4 10 non-null float64
dtypes: float64(5)
memory usage: 528.0 bytes
#df.describe() # 对于数据类型为数值型的列,查询其描述性统计的内容
df.describe()
#s.value_counts(dropna=False) # 查询每个独特数据值出现次数统计
#dropna=False为计算nan的数量
s = pd.Series([1,2,3,3,4,np.nan,5,5,5,6,7])
s.value_counts(dropna=False)
- 输出结果
5.0 3
3.0 2
7.0 1
6.0 1
4.0 1
NaN 1
2.0 1
1.0 1
dtype: int64
#df.apply(pd.Series.value_counts) # 查询数据框 (Data Frame) 中每个列的独特数据值出现次数统计
df.apply(df.value_counts)
数据的选取
- 选取列
- df[col]:以数组 Series 的形式返回选取的列
- df[[col1, col2]]:以新的数据框(DataFrame)的形式返回选取的列
- 选取行
- df.iloc[0,:]:选取第一行
- df.iloc[0,0]:选取第一行的第一个元素
- s.iloc[0]:按照位置选取行
#df[col] # 以数组 Series 的形式返回选取的列
df = pd.DataFrame(np.random.rand(5,5),columns=list('ABCDE'))
print(df)
df['C']
- 输出结果
A B C D E
0 0.392882 0.186349 0.679356 0.518771 0.856577
1 0.772426 0.523026 0.446114 0.227743 0.156144
2 0.055333 0.358384 0.848030 0.962028 0.562657
3 0.129864 0.378202 0.858732 0.377576 0.213878
4 0.189561 0.201544 0.056051 0.353937 0.175599
0 0.679356
1 0.446114
2 0.848030
3 0.858732
4 0.056051
Name: C, dtype: float64
#df[[col1, col2]] # 以新的数据框(DataFrame)的形式返回选取的列
#注意是两个方括号
df = pd.DataFrame(np.random.rand(5,5),columns=list('ABCDE'))
df[['B','E']]
df.iloc[0,:] # 选取第一行
- 输出结果
A 0.392882
B 0.186349
C 0.679356
D 0.518771
E 0.856577
Name: 0, dtype: float64
df = pd.DataFrame(np.random.rand(5,5),columns=list('ABCDE'))
df.iloc[0,0] # 选取第一行的第一个元素
- 输出结果
0.6393578066458864
#s.iloc[0] # 按照位置选取行
s = pd.Series(np.array(['I','Love','Data']))
print(s)
print("-----")
print(s.iloc[1])
print("-----")
print(s[1])
- 输出结果
0 I
1 Love
2 Data
dtype: object
-----
Love
-----
Love
#s.loc['index_one'] # 按照索引选取
s = pd.Series(np.array(['I','Love','Data']))
s.loc[1]
- 输出结果
'Love'
数据的清洗
- 重命名数据框的列名称:df.columns = [‘a’,‘b’]
- 检查数据中空值出现的情况,并返回一个由布尔值(True,Fale)组成的列:pd.isnull()
- 检查数据中非空值出现的情况,并返回一个由布尔值(True,False)组成的列:pd.notnull()
- 移除数据框 DataFrame 中包含空值的行:df.dropna()
- 移除数据框 DataFrame 中包含空值的列:df.dropna(axis=1)
- 将数据框 DataFrame 中的所有空值替换为 x:df.fillna(x)
- 将所有空值替换为平均值:s.fillna(s.mean())
- 将数组(Series)的格式转化为浮点数:s.astype(float)
- 将数组(Series)中的所有1替换为’one’:s.replace(1,‘one’)
- 将全体列重命名:df.rename(columns=lambda x: x + 2)
- 改变索引:df.set_index(‘column_one’)将df中的一列作为索引
- 改变全体索引:df.rename(index = lambda x: x+ 1)
#df.columns = ['a','b'] # 重命名数据框的列名称
df = pd.DataFrame({'A':np.array([1,np.nan,2,3,6,np.nan]),
'B':np.array([np.nan,4,np.nan,5,9,np.nan]),
'C':'foo'})
print(df)
df.columns = ['a','b','c']
df
#pd.isnull() # 检查数据中空值出现的情况,并返回一个由布尔值(True,Fale)组成的列
df = pd.DataFrame({'A':np.array([1,np.nan,2,3,6,np.nan]),
'B':np.array([np.nan,4,np.nan,5,9,np.nan]),
'C':'foo'})
pd.isnull(df)
#pd.notnull() # 检查数据中非空值出现的情况,并返回一个由布尔值(True,False)组成的列
pd.notnull(df)
#df.dropna() # 移除数据框 DataFrame 中包含空值的行
df.dropna()
#df.dropna(axis=1) # 移除数据框 DataFrame 中包含空值的列
df.dropna(axis=1)
#df.dropna(axis=0,thresh=n)
df = pd.DataFrame({'A':np.array([1,np.nan,2,3,6,np.nan]),
'B':np.array([np.nan,4,np.nan,5,9,np.nan]),
'C':'foo'})
print(df)
test = df.dropna(axis=1,thresh=1)
test
#df.fillna(x) # 将数据框 DataFrame 中的所有空值替换为 x
df.fillna('x')
#s.fillna(s.mean()) -> 将所有空值替换为平均值
s = pd.Series(np.array([1,2,3,4,np.nan]))
s.fillna(s.mean())
- 输出结果
0 1.0
1 2.0
2 3.0
3 4.0
4 2.5
dtype: float64
df = pd.DataFrame({'A':np.array([1,np.nan,2,3,6,np.nan]),
'B':np.array([np.nan,4,np.nan,5,9,np.nan])
})
print(df)
df.fillna(df.mean())
#s.astype(float) # 将数组(Series)的格式转化为浮点数
s = pd.Series([1,3,5,np.nan,7,9,9])
print(s)
s.astype(float)
- 输出结果
0 1.0
1 3.0
2 5.0
3 NaN
4 7.0
5 9.0
6 9.0
dtype: float64
0 1.0
1 3.0
2 5.0
3 NaN
4 7.0
5 9.0
6 9.0
dtype: float64
s.replace(1,'one') # 将数组(Series)中的所有1替换为'one'
- 输出结果
0 one
1 3.0
2 5.0
3 NaN
4 7.0
5 9.0
6 9.0
dtype: object
s.replace([1,3],['one','three']) # 将数组(Series)中所有的1替换为'one', 所有的3替换为'three'
- 输出结果
0 one
1 three
2 5.0
3 NaN
4 7.0
5 9.0
6 9.0
dtype: object
#df.rename(columns=lambda x: x + 2) # 将全体列重命名
df = pd.DataFrame(np.random.rand(4,4))
print(df)
df.rename(columns=lambda x: x+ 2)
#df.rename(columns={'old_name': 'new_ name'}) # 将选择的列重命名
df = pd.DataFrame(np.random.rand(10,5),columns=list('ABCDE'))
print(df)
df.rename(columns={'A':'newA','C':'newC'})
#df.set_index('column_one') # 改变索引
df = pd.DataFrame(np.random.rand(10,5),columns=list('ABCDE'))
print(df)
df.set_index('B')
#df.rename(index = lambda x: x+ 1) # 改变全体索引
df = pd.DataFrame(np.random.rand(10,5))
print(df)
df.rename(index = lambda x: x+ 1)
数据的过滤(filter),排序(sort)和分组(groupby)
df = pd.DataFrame(np.random.rand(10,5),columns=list('ABCDE'))
print(df)
- 输出结果
A B C D E
0 0.601053 0.573565 0.836974 0.658605 0.830938
1 0.059302 0.353587 0.513705 0.656726 0.139989
2 0.252286 0.878826 0.049156 0.417498 0.571945
3 0.267167 0.775165 0.492413 0.614786 0.264115
4 0.139825 0.940257 0.293432 0.461542 0.138061
5 0.886448 0.486807 0.914528 0.599247 0.543496
6 0.380719 0.297325 0.308344 0.706765 0.888145
7 0.611720 0.999417 0.212681 0.730247 0.213721
8 0.030874 0.505999 0.316796 0.862693 0.069417
9 0.192617 0.084684 0.398076 0.927433 0.489947
#df[df[col] > 0.5] # 选取数据框df中对应行的数值大于0.5的全部列
df[df["A"]>0.5]
#df[(df[col] > 0.5) & (df[col] < 0.7)] # 选取数据框df中对应行的数值大于0.5,并且小于0.7的全部列
df[(df["D"] > 0.5) & (df["B"] < 0.7)]
#df.sort_values(col1) # 按照数据框的列col1升序(ascending)的方式对数据框df做排序
df.sort_values("A")
#df.sort_values(col2,ascending=False) # 按照数据框的列col2降序(descending)的方式对数据框df做排序
df.sort_values("A",ascending = False)
#df.sort_values([col1,col2],ascending=[True,False]) # 按照数据框的列col1升序,col2降序的方式对数据框df做排序
df.sort_values(["A","B"],ascending = [True,False])
#df.groupby(col) # 按照某列对数据框df做分组
df = pd.DataFrame({'A':np.array(['foo','foo','foo','foo','bar','bar']),
'B':np.array(['one','one','two','two','three','three']),
'C':np.array(['small','medium','large','large','small','small']),
'D':np.array([1,2,2,3,3,5])})
df
df.groupby('A').count()
#df.groupby([col1,col2]) # 按照列col1和col2对数据框df做分组
df[["B","D"]].groupby(['B','D']).sum()
df.groupby("B").count()
#df.groupby(col1)[col2].mean() # 按照列col1对数据框df做分组处理后,返回对应的col2的平均值
print(df.groupby('B')['D'].mean())
print(df.groupby('B')['D'].sum())
- 输出结果
B
one 1.5
three 4.0
two 2.5
Name: D, dtype: float64
B
one 3
three 8
two 5
Name: D, dtype: int32
#df.pivot_table(index=col1,values=[col2,col3],aggfunc=mean) # 做透视表,索引为col1,针对的数值列为col2和col3,分组函数为平均值
df.pivot_table(df,index=['A','B'],
columns=['C'],aggfunc=np.sum)
#df.groupby(col1).agg(np.mean)
df.groupby('A').agg(np.mean)
#df.apply(np.mean) # 对数据框df的每一列求平均值
df = pd.DataFrame(np.random.rand(10,5),columns=list('ABCDE'))
print(df)
df.apply(np.mean)
- 输出结果
A B C D E
0 0.364793 0.828703 0.017199 0.541652 0.587749
1 0.886629 0.625196 0.851928 0.003990 0.815234
2 0.679766 0.988798 0.128338 0.751804 0.717242
3 0.774852 0.639799 0.641856 0.685501 0.814179
4 0.421538 0.077434 0.513442 0.018761 0.386801
5 0.601300 0.275986 0.796488 0.832559 0.058823
6 0.467172 0.208401 0.380636 0.419302 0.597200
7 0.362045 0.053134 0.599553 0.294281 0.074082
8 0.881448 0.404887 0.227112 0.407482 0.513640
9 0.310877 0.184919 0.082787 0.915722 0.788908
A 0.575042
B 0.428726
C 0.423934
D 0.487105
E 0.535386
dtype: float64
df.apply(np.max,axis=1) # 对数据框df的每一行求最大值
- 输出结果
0 0.828703
1 0.886629
2 0.988798
3 0.814179
4 0.513442
5 0.832559
6 0.597200
7 0.599553
8 0.881448
9 0.915722
dtype: float64
数据的连接(join)与组合(combine)
- 在这里借用一下喜乐君tableau博客中的概念
- 一般对于数据的合并分为数据并集(union)以及数据连接(join)
- 数据并集:数据上下追加,行数增加,列数不变
- python中使用df1.append(df2) 同pd.concat([df1,df2],axis=0)
- python中存在一种左右拼接方式,将df1与df2直接根据行索引连接起来
- 如果行索引相同,行数不变,列数增加
- 如果行索引不同,行数增加,列数也增加
- python中使用pd.concat([df1,df2],axis=1)
- 数据连接:数据左右连接,行数不确定,列数增加
- 一般在mysql中可以实现内连、左连、右连,不能进行完全连接
- python中使用df1.join(df2, on=‘key’),使用的是df2的行索引进行连接的
- jion操作可以直接用index来连接,但是要求两个dataframe要有一样的index但不能有重叠的列
- 通常来说一般是使用两个表格中的主键进行连接的,在这里python使用的是pd.merge(df1,df2,on="",how="")
- 其中on后接连接的列名,若是两个不同的列名,使用pd.merge(df1,df2,left_on=‘key_1’,
right_on=‘key_2’,how="")- 如果不指定连接的列名,python会自动匹配两个df中相同的列名
- 其中how可以是inner(默认)、left、right、outer
- 注意df1,df2的位置,位于左边的属于左边的表格,位于右边属于右边的表格
- 连接的两个列会只保留一个列
数据并集
- 使用df1.append(df2) 同pd.concat([df1,df2],axis=0)
#df1.append(df2) # 在数据框df2的末尾添加数据框df1,其中df1和df2的列数应该相等
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']},
index=[0, 1, 2, 3])
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
'B': ['B4', 'B5', 'B6', 'B7'],
'C': ['C4', 'C5', 'C6', 'C7'],
'D': ['D4', 'D5', 'D6', 'D7']},
index=[4, 5, 6, 7])
print(df1)
print(df2)
- 输出结果
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
A B C D
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
df1.append(df2)
数据左右拼接
- python中使用pd.concat([df1,df2],axis=1)
#pd.concat([df1, df2],axis=1) # 在数据框df1的列最后添加数据框df2,其中df1和df2的行数应该相等
pd.concat([df1,df2],axis=1)
df3 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']},
index=[0, 1, 2, 3])
df4 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
'B': ['B4', 'B5', 'B6', 'B7'],
'C': ['C4', 'C5', 'C6', 'C7'],
'D': ['D4', 'D5', 'D6', 'D7']},
index=[0, 1, 2, 3])
pd.concat([df3,df4],axis=1)
数据连接
- 方式一
- python中使用df1.join(df2, on=‘key’),使用的是df2的行索引进行连接的
- jion操作可以直接用index来连接,但是要求两个dataframe要有一样的index但不能有重叠的列
- 这种方式必须存在df1行索引与df2列中的字段内容相同
- 或者两者的行索引相同
#df1.join(df2,on=col1,how='inner') # 对数据框df1和df2做内连接,其中连接的列为col1
df5 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'key': ['K0', 'K1', 'K0', 'K1']})
df6 = pd.DataFrame({'C': ['C0', 'C1'],
'D': ['D0', 'D1']},
index=['K0', 'K1'])
print(df5)
print(df6)
- 输出结果
A B key
0 A0 B0 K0
1 A1 B1 K1
2 A2 B2 K0
3 A3 B3 K1
C D
K0 C0 D0
K1 C1 D1
df5.join(df6, on='key')
df1 = pd.DataFrame({'key1': ['a', 'b', 'c', 'a', 'b'],
'data1': range(5)},
index=['K0', 'K1','K2','K3', 'K4'])
df2 = pd.DataFrame({'key2': ['a', 'b', 'd'],
'data2': range(3)},
index=['K0', 'K1','K2'])
print(df1)
print(df2)
- 输出结果
key1 data1
K0 a 0
K1 b 1
K2 c 2
K3 a 3
K4 b 4
key2 data2
K0 a 0
K1 b 1
K2 d 2
df1.join(df2,how = 'inner')
- 方式二
- pd.merge(df1,df2,on="",left_on=‘key_1’, right_on=‘key_2’,how="")
df1 = pd.DataFrame({'key': ['a', 'b', 'c', 'a', 'b'],
'data1': range(5)})
df2 = pd.DataFrame({'key': ['a', 'b', 'd'],
'data2': range(3)})
df1
df2
#默认使用内连接inner join
pd.merge(df1,df2)
pd.merge(df1,df2,on='key',how='left')
pd.merge(df1,df2,on='key',how='right')
pd.merge(df1,df2,on='key',how='outer')
数据的统计
- 1.df.describe():df每一列的描述性统计
- 2.df.mean():df中每一列的平均值
- 3.df.corr():df中每一列与其他列的相关系数
- 4.df.count():df中每一列的非空值个数
- 5.df.max():df中每一列的最大值
- 6.df.min():df中每一列的最小值
- 7.df.median():df中每一列的中位数
- 8.df.std():df中每一列的标准差
#df.describe() # 得到数据框df每一列的描述性统计
df = pd.DataFrame(np.random.rand(10,5),columns=list('ABCDE'))
print(df)
df.describe()
#df.mean() # 得到数据框df中每一列的平均值
df.mean()
- 输出结果
A 0.471350
B 0.439164
C 0.569356
D 0.595874
E 0.431748
dtype: float64
#df.corr() # 得到数据框df中每一列与其他列的相关系数
df.corr()
#df.count() # 得到数据框df中每一列的非空值个数
df.count()
- 输出结果
A 10
B 10
C 10
D 10
E 10
dtype: int64
#df.max() # 得到数据框df中每一列的最大值
df.max()
- 输出结果
A 0.888019
B 0.906654
C 0.995770
D 0.974866
E 0.847611
dtype: float64
#df.min() # 得到数据框df中每一列的最小值
df.min()
- 输出结果
A 0.230401
B 0.046359
C 0.243377
D 0.250055
E 0.103578
dtype: float64
#df.median() # 得到数据框df中每一列的中位数
df.median()
- 输出结果
A 0.385917
B 0.466891
C 0.577356
D 0.549365
E 0.395121
dtype: float64
#df.std() # 得到数据框df中每一列的标准差
df.std()
- 输出结果
A 0.206019
B 0.278955
C 0.264849
D 0.257765
E 0.241896
dtype: float64