pandas

Posted 我怕是有点打脑壳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pandas相关的知识,希望对你有一定的参考价值。

Pandas

文件读写

读取

  • pd.read_csv() 读取csv
  • pd.read_excel()读取excel
  • pd.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()
SchoolGradeNameGenderWeightTransfer
0Shanghai Jiao Tong UniversityFreshmanGaopeng YangFemale46.0N
1Peking UniversityFreshmanChangqiang YouMale70.0N
2Shanghai Jiao Tong UniversitySeniorMei SunMale89.0N
3Fudan UniversitySophomoreXiaojuan SunFemale41.0N
4Fudan UniversitySophomoreGaojuan YouMale74.0N



行和列

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
SchoolGender
Name
Qiang SunTsinghua UniversityFemale
Qiang SunTsinghua UniversityFemale
Qiang SunShanghai Jiao Tong UniversityFemale
Quan ZhaoShanghai Jiao Tong UniversityFemale



切片

​ Series 使用字符串索引时提到,如果是唯一值的起点和终点字符,那么就可以使用切片,并且包含两个端点,如果不唯一则报错

#两个端点都包含
df_demo.loc['Gaojuan You':'Gaoqiang Qian', 'School':'Gender']
SchoolGradeGender
Name
Gaojuan YouFudan UniversitySophomoreMale
Xiaoli QianTsinghua UniversityFreshmanFemale
Qiang ChuShanghai Jiao Tong UniversityFreshmanFemale
Gaoqiang QianTsinghua UniversityJuniorFemale

​ 需要注意的是,如果 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()
SchoolGradeGenderWeightTransfer
Name
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Gaojuan YouFudan UniversitySophomoreMale74.0N
Xiaopeng ZhouShanghai Jiao Tong UniversityFreshmanMale74.0N
Xiaofeng SunTsinghua UniversitySeniorMale71.0N
Qiang ZhengShanghai Jiao Tong UniversitySeniorMale87.0N
  • 传入元素列表,也可以通过 isin 方法返回的布尔列表等价写出
# 选出所有大一和大四的同学信息
df_demo.loc[df_demo.Grade.isin(['Freshman', 'Senior'])].head()
#isin是dataframe的一个方法
SchoolGradeGenderWeightTransfer
Name
Gaopeng YangShanghai Jiao Tong UniversityFreshmanFemale46.0N
Changqiang YouPeking UniversityFreshmanMale70.0N
Mei SunShanghai Jiao Tong UniversitySeniorMale89.0N
Xiaoli QianTsinghua UniversityFreshmanFemale51.0N
Qiang ChuShanghai Jiao Tong UniversityFreshmanFemale52.0N
  • 对于复合条件而言,可以用 |(或), &(且), ~(取反) 的组合来实现
#选出复旦大学中体重超过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]
SchoolGradeGenderWeightTransfer
Name
Qiang HanPeking UniversityFreshmanMale87.0N
Chengpeng ZhouFudan UniversitySeniorMale81.0N
Changpeng ZhaoPeking Univers

以上是关于pandas的主要内容,如果未能解决你的问题,请参考以下文章

如何将标量 Pyspark UDF 转换为 Pandas UDF?

无法在 pyspark 中应用标量 pandas udf

将 MultiIndex Pandas 数据帧乘以来自另一个数据帧的多个标量

Pandas只能将大小为1的数组转换为Python标量

pandas 比较引发 TypeError:无法将 dtyped [float64] 数组与 [bool] 类型的标量进行比较

Pandas ValueError:只能将大小为1的数组转换为Python标量

(c)2006-2024 SYSTEM All Rights Reserved IT常识