##前言
在前面提到的是数据处理三剑客中的numpy,这一偏来说一下三剑客另外一剑-pandas
简介
pandas是基于numpy的一种工具,他也是为了解决数据分析来创建的,pandas的series拥有numpy的所有功能,而且pandas拥有dataframe拥有更强大的功能
pandas中的数据类型
pandas有两种数据类型:series与dataframe
series是一种一维的数据类型,其功能与numpy相同, 可以把它当作一个由带标签的元素组成的 numpy 数组。标签可以是数字或者字符
dataframe是一个二维的数据类型,就像是csv与excel存储的数据一样
pandas的数据定义
定义个series
s1 = pd.Series([1, 2, 3])
print(s1)
print('获取第一个值:', s1[0])
s2 = pd.Series([1, 2, 3], index=['a', 'b', 'c']) #自定义series的索引
print(s2)
print('索引为a的值:', s2['a'])
输出
0 1
1 2
2 3
dtype: int64
获取第一个值: 1
a 1
b 2
c 3
dtype: int64
索引为a的值: 1
定义一个dataframe
data = [[0, 150], [0, 150], [0, 150], [0, 300]]
index = ['语文', '数学', '英语', '理综']
columns = ['李四', '张三']
df = DataFrame(data=data, index=index, columns=columns)
print(df) #定义的dataframe数据
输出
李四 张三
语文 0 150
数学 0 150
英语 0 150
理综 0 300
pandas的常用方法
查看前几行的数据
df.head(3)
输出
李四 张三
语文 0 150
数学 0 150
英语 0 150
head方法还可以传入负数,传入负数可以看做从倒数第几位往前取值.
查看后几行的数据
print(df.tail(3))
输出
李四 张三
数学 0 150
英语 0 150
理综 0 300
dataframe重命名
df.columns = [2, 1]
# or
df.rename(columns={
'李四': 2,
'张三': 1
}, inplace=True)
print(df)
输出
2 1
语文 0 150
数学 0 150
英语 0 150
理综 0 300
这两种方法都可以将张三和李四改成2和1,我是使用第二种方法,其中第二种方法的inplace参数,它为True,则在原有df上更改,为false则copy一个新的df
求dataframe的长度
print('dataframe有多少行:', len(df))
print('datafram行数和列数:', df.shape)
输出
dataframe有多少行: 4
datafram行数和列数: (4, 2)
去除重复行
df.drop_duplicates('张三', keep='last', inplace=True) #去重,并保留最后一个
print(df)
输出
李四 张三 类型
数学 0 150 主修
英语 0 100 非主修
理综 0 300 非主修
获取基本统计数据
pd.options.display.float_format = '{:,.3f}'.format #只小数点后三位
输出
李四 张三
count 4.000 4.000
mean 0.000 187.500
std 0.000 75.000
min 0.000 150.000
25% 0.000 150.000
50% 0.000 150.000
75% 0.000 187.500
max 0.000 300.000
dataframe的筛选 获取某一列
print(df.张三) #获取张三那一列
print(df['张三'])
输出
语文 150
数学 150
英语 150
理综 300
Name: 张三, dtype: int64
当我们提取列的时候,提取的是series,我们可以吧dataframe看做是series的一个字典,所以在获取列的时候,我们就会得到一个 series
按条件获取某一列(布尔过滤(boolean masking))
print(df[df['张三'] > 150]) #和numpy的使用方法类似
输出
李四 张三
理综 0 300
复合条件过滤
d = df[(df['张三'] > 100) & (df['张三'] < 300)]
print(d)
输出
李四 张三
语文 0 150
数学 0 150
英语 0 150
这里不能用 and 关键字,因为会引发操作顺序的问题,而且使用and会报错
按照字符串开头过滤
df['李四'] = '1000'
d = df[df['李四'].str.startswith('100')]
print(d)
输出
李四 张三
语文 1000 150
数学 1000 150
英语 1000 150
理综 1000 300
索引
刚才是获取某一列的数据,我们获取行数据的话是有专门的方法
print(df.iloc[30]) #iloc是获取第多少行的值
print(df.loc['理综']) #loc是根据索引名来获取值
输出
李四 0
张三 300
Name: 理综, dtype: int64
对数据集应用函数
有时需要根据数据的不同来对数据进行不同的处理,这时候我们就需要用到apply或者applymap函数了
def level(scroll):
l = 'A' if scroll > 150 else 'B'
return l
df['level'] = df['张三'].apply(level)
print(df)
#直接用dataframe调用apply方法
def level(data):
if data['张三'] - data['李四'] >= 0:
return 1
return 0
df['level'] = df.apply(level, axis=1)
print(df)
输出
李四 张三 level
语文 0 150 B
数学 0 150 B
英语 0 150 B
理综 0 300 A
applymap
def level(scroll):
l = 'A' if scroll > 150 else 'B'
return l
df = df.applymap(level)
print(df)
输出
李四 张三
语文 B B
数学 B B
英语 B B
理综 B A
排序操作
按照索引排序
data = [[0, 150], [0, 150], [0, 150], [0, 300]]
index = [1, 3, 2, 4]
columns = ['李四', '张三']
df = DataFrame(data=data, index=index, columns=columns)
df = df.sort_index()
print(df)
输出
李四 张三
1 0 150
2 0 150
3 0 150
4 0 300
按照value进行排序
df = df.sort_values(by='张三', ascending=False) #ascending为True是从小到大,默认为True
print(df)
输出
李四 张三
4 0 300
1 0 150
3 0 150
2 0 150
数据集操作
数据集操作就是重新建立数据结构,使数据集呈现一种更方便并且有用的形式
首先,是<font color=#b73559> grouypby </font>
d_max = df['张三'].groupby(df['类型']).max() #按照类型聚合张三并取最大值
print(d_max)
d_min = df['张三'].groupby(df['类型']).min() #按照类型聚合张三并取最小值
print(d_min)
d_cumsum = df['张三'].groupby(df['类型']).cumsum() #按照类型聚合张三并按照挨着的同一类型从上到下累加(一般先根据某一类型排序,整合到一起,在累加)
print(d_cumsum)
#还可以直接用整体的dataframe来groupby,与上面使用方法相同
all_max = df.groupby(df['类型']).max()
print(all_max)
all_cumsum = df.groupby(df['类型']).cumsum()
print(all_cumsum)
groupby也可以按照多列进行分组
合并数据集
在进行数据处理的时候,经常需要用到数据合并,然后统一进行来操作。
首先,是<font color=#b73559> merge </font>
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'), copy=True, indicator=False,
validate=None)
| 缩略| 含义 | | — | — | | left | 基类dataframe | | right | 想要合并的frame | | how | 合并方式,支持 left、right、outer、inner(默认) | | on | 指定需要合并的列 | | left_on | left用作连接键的列,与right_on一起使用 | | right_on | right用作连接键的列,与left_on一起使用 | | suffixes | 用于追加到重叠列名的末尾,默认为(‘_x’,‘_y’)。如果左右两个DataFrame对象都有“data”,则结果就会出现“data_x”和“data_y” |
实现起来很简单
data = [['001', 80, 70], ['002', 90, 60], ['003', 100, 50]]
columns = ['id', '语文', '数学']
df1 = DataFrame(data=data,columns=columns)
data = [['001', 80, 70], ['002', 90, 60], ['004', 100, 50]]
columns = ['id', '英语', '理综']
df2 = DataFrame(data=data, columns=columns)
all_df = pd.merge(df1, df2, how='left', on='id')
print(all_df)
输出
id 语文 数学 英语 理综
0 001 80 70 80.0 70.0
1 002 90 60 90.0 60.0
2 003 100 50 NaN NaN
outer、right、inner与left同理
数据空值处理
在合并的时候,我们发现会有一些值是NaN,这些值可能需要我们手动处理一下
首先,发现空值<font color=#b73559> isnull() </font>和<font color=#b73559> notnull() </font>
print(all_df.isnull())
输出
id 语文 数学 英语 理综
0 False False False False False
1 False False False False False
2 False False False True True
我个人是没怎么用过这个方法的,感觉没什么用
删除有空值的行或列 <font color=#b73559> dropna(axis=0, how=’any’, inplace=False) </font>
print(all_df.dropna(axis=0))
输出
id 语文 数学 英语 理综
0 001 80 70 80.0 70.0
1 002 90 60 90.0 60.0
很重要的一个方法,填充NaN值<font color=#b73559> fillna()</font>
print(all_df.fillna(value=0))
输出
id 语文 数学 英语 理综
0 001 80 70 80.0 70.0
1 002 90 60 90.0 60.0
2 003 100 50 0.0 0.0