pandas
Posted 我怕是有点打脑壳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pandas相关的知识,希望对你有一定的参考价值。
Pandas
文件读写
读取
pd.read_csv()
读取csvpd.read_excel()
读取excelpd.read_txt()
读取文本文档
公共参数:
header=None 从第几行开始读取
index_col 指定行索引
usecols 读取那几列
parse_dates 把给出的列转化为时间序列
nrows 读取的行数
在读取txt文件时经常遇到分隔符不是空格,read_table()有一个分隔参数叫sep自定义分隔符(可以写正则表达式)
写入
一般在写入时把 index
设置为 False
,当索引没有使用意义时就要去掉
普通写入
to_csv
to_excel
以下需要安装tabulate包
to_markdown
to_latex
基本数据结构
Series
是 一维 的数据结构
pd.Series(data,index,dtype,name)
参数:
data = 值
index = 索引
dtype = 存储类型
name = 序列名字
#示例
pd.Series(data = [100,'a','dict':5],
index = pd.Index(
['id1',20,'thrid'],
name='my_index'),
dtype='object',
name = 'my_name')
my_index
id1 100
20 a
thrid 'dict': 5
Name: my_name, dtype: object
object类型
代表一种混合类型,目前pandas把 字符串数组 认为是object类型
Dataframe
相当于 二维 数组,由Series组成
data = [[1,'a',1.2],[2,'b',2.2],[3,'c',3.2]]
df = pd.DataFrame(data=data,
index = ['row_%d'%i for i in range(3)],
columns=['col_0','col_1','col_2'])
print(df)
col_0 col_1 col_2
row_0 1 a 1.2
row_1 2 b 2.2
row_2 3 c 3.2
属性
df.values
查看值df.index
查看行索引df.dtypes
查看每列的类型df.shape
查看形状维度df.T
转置
常用基本函数
df.head(n)
查看数据的前n行df.tail(n)
查看数据的后n行df.info()
返回表的信息概况(如果有中文会报错)df.describe(n)
汇总统计函数
统计函数
df.std()
标准差df.var()
方差df.corr()
于原始DataFrame列与列之间相关性的DataFrame对象。df.quantile()
分位数- 所谓四分位数;即把数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数。
- 第1四分位数 (Q1),又称“较小四分位数”,等于该样本中所有数值由小到大排列后第25%的数字。
- 第2四分位数 (Q2),又称“中位数”,等于该样本中所有数值由小到大排列后第50%的数字。
- 第3四分位数 (Q3),又称“较大四分位数”,等于该样本中所有数值由小到大排列后第75%的数字。
df.count()
非缺失值个数df.idxmax()
最大值对应的索引
唯一值函数
-
df.unique()
把去掉重复值的数据输出 -
df.nunique()
数据中唯一数据的个数 -
df.value_counts()
得到重复值的数据和他出现的频数 -
df.drop_duplicates()
多列去重-
''' df.drop_duplicates参数 subset: 列名,可选,默认为None keep: ‘first’, ‘last’, False, 默认值 ‘first’ first: 保留第一次出现的重复行,删除后面的重复行。 last: 删除重复项,除了最后一次出现。 False: 删除所有重复项。 inplace:布尔值,默认为False,是否直接在原数据上删除重复项或删除重复项后返回副本。(inplace=True表示直接在原来的DataFrame上删除重复项,而默认值False表示生成一个副本。) '''
-
df.duplicated()返回是否为唯一值的布尔列表,参数与drop_duplicates一致,如果元素是重复的都会标上True,否则False,drop_duplicates等价于把duplicated为True的对应行删除
-
替换函数
pandas中可以分为三类:
映射替换,逻辑替换,数值替换
映射替换
-
df.replace(old, new[, max])
-
- old -- 将被替换的子字符串。 - new -- 新字符串,用于替换old子字符串。 - max -- 可选字符串, 替换不超过 max 次
可以直接给予 字典 来替换数据
-
-
特殊方向替换
-
指定method = ffill/bfill
-
用 前面最近的未被替换掉 的值进行替换 用 后面最近的未被替换掉 的值进行替换
-
s = pd.Series(['a',1,'b',2,1,1,'a'])
print('ffill:\\n',s.replace([1,2],method='ffill'))
print('\\nbfill:\\n',s.replace([1,2],method='bfill'))
ffill:
0 a
1 a
2 b
3 b
4 b
5 b
6 a
dtype: object
bfill:
0 a
1 b
2 b
3 a
4 a
5 a
6 a
dtype: object
逻辑替换
df.where(condition)
传入条件为False
的对应行进行替换df.mask(condition)
传入条件为True
的对应行进行替换
传入的条件也可以是Serise对象,只要是序列一致的布尔序列即可
s_condition = pd.Series([True,False,False,True],index=s.index)
s.mask(s_condition,0)
0 0.00000
1 1.23456
2 100.00000
3 0.00000
dtype: float64
数值替换
-
df.round(n)
返回小数位为n位的四舍五入的float值 -
df.abc()
取绝对值 -
df.clip(lower, upper, axis, inplace)
-
lower : float或array_like,默认为None 最小阈值。低于此阈值的所有值都将设置为它 upper : float或array_like,默认为None 最大阈值。高于此阈值的所有值都将设置为它 axis : int或string轴名称,可选 沿给定轴将对象与下部和上部对齐 inplace : 布尔值,默认为False 是否对数据执行操作
-
排序函数
sort_values()
值排序
被排序的列可以是列表来进行多列排序
print('年龄用降序排序,工资用升序排序')
print(s.head().sort_values(['年龄','工资(元)'],ascending=[False,True]))
#因为在实操种可能有一些数据相同,索引就需要多列排序的操作,排在前面的先拍
年龄用降序排序,工资用升序排序
序号 姓名 年龄 工资(元)
1 2 黄丽 32 3600
0 1 张茜 28 2900
4 5 曾丽萍 27 2500
3 4 邓大海 26 2200
2 3 李海涛 24 2800
sort_index()
索引排序
可以先指定索引列(level),字符串排序由字母顺序决定
print('以名字进行索引升序排序\\n')
s.head().sort_index(level='姓名',ascending=True)
#看得出来是A-Z是升序,Z-A是降序
以名字进行索引升序排序
序号 姓名 年龄 工资(元)
0 1 张茜 28 2900
1 2 黄丽 32 3600
2 3 李海涛 24 2800
3 4 邓大海 26 2200
4 5 曾丽萍 27 2500
apply方法
apply用与DataFrame的 行迭代 和 列迭代
-
DataFrame.apply(func,axis,raw,result_type)
-
func: 应用于每一列或每一行的函数。 axis: 0 或 'index',1 或 'columns',默认 0 沿其应用函数的轴: 0 或“索引”:将函数应用于每一列。 1 或“列”:将函数应用于每一行。 raw: 布尔值,默认为 False 确定行或列是否作为 Series 或 ndarray 对象传递: False: 将每一行或每一列作为一个系列传递给函数。 True:传递的函数将接收 ndarray 对象。如果您只是应用NumPy 缩减功能,这将获得更好的性能。 result_type 'expand', 'reduce', 'broadcast','None',默认无 axis=1这些仅在(列)时起作用: 'expand' : 类似列表的结果将变成列。 'reduce' :如果可能,返回一个系列,而不是扩展类似列表的结果。这与“扩展”相反。 'broadcast' : 结果将被广播到DataFrame的原始形状,原始索引和列将被保留。 默认行为(None)取决于应用函数的返回值:类似列表的结果将作为这些结果的系列返回。但是,如果应用函数返回一个系列,这些将扩展为列。
-
df_demo = s[['年龄','工资(元)']]
#先把需要遍历的列或行提取出来
print('不用apply函数的平均值:\\n',df_demo.mean())
def func(x):
res = x.mean()
return res
print('\\n使用了apply函数的平均值\\n',df_demo.apply(func,axis=1))
不用apply函数的平均值:
年龄 30.763889
工资(元) 3059.722222
dtype: float64
使用了apply函数的平均值
0 1464.0
1 1816.0
2 1412.0
3 1113.0
4 1263.5
...
67 1919.0
68 1617.0
69 1263.0
70 1917.5
71 2273.0
Length: 72, dtype: float64
apply的自由度很高但是代价是性能,所以一般少用apply
mad
mad
函数返回的是一个序列中偏离该序列均值的绝对值大小的均值
例如序列1,3,7,10中,均值为5.25,每一个元素偏离的绝对值为4.25,2.25,1.75,4.75,这个偏离序列的均值为3.25。
print('mad函数输出\\n',df_demo.mad())
print('\\n使用apply输出\\n',df_demo.apply(lambda x:(x-x.mean()).abs().mean()))
mad函数输出
年龄 5.515432
工资(元) 600.231481
dtype: float64
使用apply输出
年龄 5.515432
工资(元) 600.231481
dtype: float64
窗口对象
滑动窗口rolling 扩张窗口expanding 指数加权窗口ewm
滑动窗口
rolling
滑动窗口将window参数设置为多少,就从源数据第一个元素向左边数 window参数-1(因为包括它本身) 然后进行运算,以此向后推
num5 = pd.Series([1,2,3,4,5,6])
roller = num5.rolling(window=2)
print(roller.sum())
'''
当窗口为2时,从第一个源数据元素向左数 window-1 个位 就是1个位
因为0索引左边没有任何数[本位数据为1],所以为缺失值(任何数与缺失值作运算都是缺失值)
因为1索引向左边数是1(源数据)[本位数据为2],所以求和为3
因为2索引向左边数是2(源数据)[本位数据为3],所以为5
'''
0 NaN
1 3.0
2 5.0
3 7.0
4 9.0
5 11.0
dtype: float64
另类窗口函数
他们的公共参数:periods=n
shift
向左取第n个元素的值
#shift:取向左第n个元素的值
num5 = pd.Series([1,3,6,10,15])
print('shift:\\n',num5.shift(periods=2))
print('\\n特殊用法(取负数)\\n',num5.shift(-1))
shift:
0 NaN
1 NaN
2 1.0
3 3.0
4 6.0
dtype: float64
特殊用法(取负数)
0 3.0
1 6.0
2 10.0
3 15.0
4 NaN
dtype: float64
diff
与向左第n个元素做差(与numpy不同,后者表示n阶差分)
#diff:向左取n个元素做差
num5 = pd.Series([1,3,6,10,15])
print('diff:\\n',num5.diff(2))
print('\\n特殊用法(取负数):\\n',num5.diff(-2))
diff:
0 NaN
1 NaN
2 5.0
3 7.0
4 9.0
dtype: float64
特殊用法(取负数):
0 -5.0
1 -7.0
2 -9.0
3 NaN
4 NaN
dtype: float64
pct_change
与向左第n个元素相比计算增长量(n可以为负,表示反方向的类似操作)
#pct_change:与向左第n个元素相比计算增长量
num5 = pd.Series([1,3,6,10,15])
print('pct_change:\\n',num5.pct_change(2))
print('\\n特殊用法(取负数):\\n',num5.pct_change(-2))
pct_change:
0 NaN
1 NaN
2 5.000000
3 2.333333
4 1.500000
dtype: float64
特殊用法(取负数):
0 -0.833333
1 -0.700000
2 -0.600000
3 NaN
4 NaN
dtype: float64
另类滑窗函数也可以用rolling函数来实现
扩展窗口
expanding
累计窗口函数,与滑动窗口不同的是他的窗口会动态增大,从第一个开始向右边平移n个元素进行计算
num5 = pd.Series([1,3,6,10,15])
num5.expanding().mean()
0 1.000000
1 2.000000
2 3.333333
3 5.000000
4 7.000000
dtype: float64
索引器
基本索引
行索引
一般的索引都是中括号['列名']
来索引内容,结果返回Serise(参数<=1时),如果参数>1就返回DataFrame
#读取文件
df = pd.read_csv('C:\\\\Users\\\\Yuan\\\\Desktop\\\\pandas\\\\文件\\\\data\\\\learn_pandas.csv',usecols =
['School', 'Grade', 'Name', 'Gender','Weight', 'Transfer'])
df['Name'].head()
0 Gaopeng Yang
1 Changqiang You
2 Mei Sun
3 Xiaojuan Sun
4 Gaojuan You
Name: Name, dtype: object
此外,若要取出单列,且列名中不包含空格,则可以用 .列名
取出,这和 [列名] 是等价的:
列索引
如果取出单个索引对应的元素,可以使用[index]
,若 Series
只有单个值对应,则返回这个标量值,如果有多个值对应,则返回一个 Series
s = pd.Series([1, 2, 3, 4, 5, 6],
index=['a', 'b', 'a', 'a', 'a', 'c'])
s
a 1
b 2
a 3
a 4
a 5
c 6
dtype: int64
索引切片
如果想要取出某两个索引之间的元素,并且这两个索引是在整个索引中 唯一出现 ,就可以使用 切片 (注意:索引切片会包含两个端点 )
s['c': 'b': -2]
c 6
a 4
b 2
dtype: int64
如果前后端点的值存在 重复 ,即 非唯一值 ,那么需要经过 排序 才能使用切片
#错误案例
try:
s['a','b']
except Exception as e:
Err_Msg = e
Err_Msg
KeyError('key of type tuple not found and not a MultiIndex')
如果使用整数切片,则会取出对应索引 位置
的值,注意这里的整数切片同 Python 中的切片一样 不包含右端点
s[1:-1:2]
b 2
a 4
dtype: int64
提示:
如果不想陷入麻烦,那么请不要把纯浮点以及任何混合类型(字符串、整数、浮点类型等的混合作为索引,否则可能会在具体的操作时报错或者返回非预期的结果,并且在实际的数据分析中也不存在这样做的动机。
loc索引器
是一种基于 元素 的索引器
-
语法:
df.loc[*,*]
-
第一个
*
代表行的选择,第二个*
代表列的选择,如果省略第二个位置写作 loc[ * ] ,这个*
是指行的筛选 -
其中,
*
的位置一共有五类合法对象
分别是:单个元素、元素列表、元素切片、布尔列表以及函数
-
df = pd.read_csv('C:\\\\Users\\\\Yuan\\\\Desktop\\\\pandas\\\\文件\\\\data\\\\learn_pandas.csv',usecols =
['School', 'Grade', 'Name', 'Gender','Weight', 'Transfer'])
df.head()
School | Grade | Name | Gender | Weight | Transfer | |
---|---|---|---|---|---|---|
0 | Shanghai Jiao Tong University | Freshman | Gaopeng Yang | Female | 46.0 | N |
1 | Peking University | Freshman | Changqiang You | Male | 70.0 | N |
2 | Shanghai Jiao Tong University | Senior | Mei Sun | Male | 89.0 | N |
3 | Fudan University | Sophomore | Xiaojuan Sun | Female | 41.0 | N |
4 | Fudan University | Sophomore | Gaojuan You | Male | 74.0 | N |
行和列
df_demo.loc['Qiang Sun', 'School'] # 返回Series,因为第一个是索引列
Name
Qiang Sun Tsinghua University
Qiang Sun Tsinghua University
Qiang Sun Shanghai Jiao Tong University
Name: School, dtype: object
df_demo.loc['Quan Zhao', 'School'] # 返回单个元素
'Shanghai Jiao Tong University'
元素列表
df_demo.loc[['Qiang Sun','Quan Zhao'], ['School','Gender']]#dataframe
School | Gender | |
---|---|---|
Name | ||
Qiang Sun | Tsinghua University | Female |
Qiang Sun | Tsinghua University | Female |
Qiang Sun | Shanghai Jiao Tong University | Female |
Quan Zhao | Shanghai Jiao Tong University | Female |
切片
Series 使用字符串索引时提到,如果是唯一值的起点和终点字符,那么就可以使用切片,并且包含两个端点,如果不唯一则报错
#两个端点都包含
df_demo.loc['Gaojuan You':'Gaoqiang Qian', 'School':'Gender']
School | Grade | Gender | |
---|---|---|---|
Name | |||
Gaojuan You | Fudan University | Sophomore | Male |
Xiaoli Qian | Tsinghua University | Freshman | Female |
Qiang Chu | Shanghai Jiao Tong University | Freshman | Female |
Gaoqiang Qian | Tsinghua University | Junior | Female |
需要注意的是,如果 DataFrame
使用整数索引,其使用整数切片的时候和上面字符串索引的要求一致,都是 元素 切片,包含两个端点、端点不允许有重复值
df_loc_slice_demo = df_demo.copy() # 复制下来
df_loc_slice_demo.index = range(df_demo.shape[0],0,-1) #把所以设置为全部元素记录数的降序
df_loc_slice_demo.loc[5:3]# 定位器切片,两个端点都包含
School Grade Gender Weight Transfer
5 Fudan University Junior Female 46.0 N
4 Tsinghua University Senior Female 50.0 N
3 Shanghai Jiao Tong University Senior Female 45.0 N
df_loc_slice_demo.loc[3:5]
# 没有返回,说明不是整数位置切片,要根据索引排序来切片
School Grade Gender Weight Transfer
布尔索引
传入 loc
的布尔列表与 DataFrame
长度相同,且列表为 True
的位置所对应的行会被选中, False
则会被剔除
# 选出体重超过70kg的学生
df_demo.loc[df_demo.Weight>70].head()
School | Grade | Gender | Weight | Transfer | |
---|---|---|---|---|---|
Name | |||||
Mei Sun | Shanghai Jiao Tong University | Senior | Male | 89.0 | N |
Gaojuan You | Fudan University | Sophomore | Male | 74.0 | N |
Xiaopeng Zhou | Shanghai Jiao Tong University | Freshman | Male | 74.0 | N |
Xiaofeng Sun | Tsinghua University | Senior | Male | 71.0 | N |
Qiang Zheng | Shanghai Jiao Tong University | Senior | Male | 87.0 | N |
- 传入元素列表,也可以通过
isin
方法返回的布尔列表等价写出
# 选出所有大一和大四的同学信息
df_demo.loc[df_demo.Grade.isin(['Freshman', 'Senior'])].head()
#isin是dataframe的一个方法
School | Grade | Gender | Weight | Transfer | |
---|---|---|---|---|---|
Name | |||||
Gaopeng Yang | Shanghai Jiao Tong University | Freshman | Female | 46.0 | N |
Changqiang You | Peking University | Freshman | Male | 70.0 | N |
Mei Sun | Shanghai Jiao Tong University | Senior | Male | 89.0 | N |
Xiaoli Qian | Tsinghua University | Freshman | Female | 51.0 | N |
Qiang Chu | Shanghai Jiao Tong University | Freshman | Female | 52.0 | N |
- 对于复合条件而言,可以用 |(或), &(且), ~(取反) 的组合来实现
#选出复旦大学中体重超过70kg的大四学生,或者北大男生中体重超过80kg的非大四的学生
school1 = df_demo.School == 'Fudan University'
grade1 = df_demo.Grade == 'Senior'
weight1 = df_demo.Weight > 70
FD = school1 & grade1 & weight1
school2 = df_demo.School == 'Peking University'
grade2 = df_demo.Grade == 'Senior'
weight2 = df_demo.Weight > 80
BD = school2 & (~grade2) & weight2 # (~grade2)这里是取反
df_demo.loc[FD | BD]
School | Grade | Gender | Weight | Transfer | |
---|---|---|---|---|---|
Name | |||||
Qiang Han | Peking University | Freshman | Male | 87.0 | N |
Chengpeng Zhou | Fudan University | Senior | Male | 81.0 | N |
Changpeng Zhao | Peking Univers 以上是关于pandas的主要内容,如果未能解决你的问题,请参考以下文章 如何将标量 Pyspark UDF 转换为 Pandas UDF? 将 MultiIndex Pandas 数据帧乘以来自另一个数据帧的多个标量 pandas 比较引发 TypeError:无法将 dtyped [float64] 数组与 [bool] 类型的标量进行比较 |