pandas 常见函数的使用

Posted 紫青宝剑

tags:

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

Pandas 的使用

介绍:pandas 是 python 语言的的一个关于数据分析的扩展库;pandas 可以对各种数据进行操作, pandas 依赖于 numpy ,在常规的数据分析中,pandas 的使用范围是最宽广的;

参考文章:https://www.runoob.com/pandas/pandas-tutorial.html

原则:使用pandas处理数据的时候,尽量不要使用for循环去做操作,这样会使得 pandas 失去意义;

1.安装与导入

pip install pandas

导入

import pandas as pd

2.pandas 数据结构

pandas 的数据结构主要分为SeriesDataFrame两种数据结构;

2.1 Series 数据结构

v = pd.Series([1,2,3,4,5,6])     # 构建结构
sv = pd.Series([1,2,3], index=[\'x\',\'y\',\'z\'])

使用字典直接构建数据

sites = 1: "Google", 2: "Runoob", 3: "Wiki"
myvar = pd.Series(sites)
myvar

2.2 DataFrame 数据结构

DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。

这种数据结构是我们最常用的数据结构的信息;

# 转换列表为数据对象
data = [[\'Google\',10],[\'Runoob\',12],[\'Wiki\',13]]
df = pd.DataFrame(data,columns=[\'Site\',\'Age\'],dtype=float)  # 构建对象;
df

转换字典

data = 
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]


# 数据载入到 DataFrame 对象
df = pd.DataFrame(data)

# 返回第一行
print(df.loc[0])
# 返回第二行
print(df.loc[1])

>>>
calories    420
duration     50
Name: 0, dtype: int64
calories    380
duration     40
Name: 1, dtype: int64
        
        
data = 
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]


# 数据载入到 DataFrame 对象
df = pd.DataFrame(data)

# 返回第一行和第二行
print(df.loc[[0, 1]])

3.Pandas的数据导入

数据导入主要看数据的来源与数据的形式,最常见的数据的形式是json,csv,sql,mongo,txt;

3.1 csv 数据的导入

# 读取数据消息
v = pd.read_csv(\'../data/tag.csv\')
print(v.head())    # head(10)显示头部数据信息;
print(v.tail())    # tail(10) 显示末尾的数据信息;
v = pd.read_csv(\'../data/tag.csv\', index_col=0)   # 读取数据不显示行索引;

pandas 的导入方式如上,还有原生的python操作文件的方式;

补充:.txt文件的使用是表格的时候,可以使用read_csv方法,将分隔符设置成为文件中的分隔符就可以;当.txt文件中是一段文本的时候,可以直接使用 python 的文件处理;

3.2 json 数据的导入

v = pd.read_json(\'s.json\')
print(v.head())

3.3 sql 数据读取

import pandas as pd

from utils.db import db

# 已经封装好的模块获取数据库连接池中的连接;
conn = db.get_conn_cursor()[0]
sql_str = "select * from blogs"
v = pd.read_sql(sql_str, con=conn)
print(v.head())

说明: SQL 语句本身具备数据筛选与过滤的作用,如果可以在数据读取的时候直接使用复杂的 SQL 过滤掉一部分的数据,可以为数据预处理的部分省去很多的事情;

3.4 读取Mongo

pandas 读取 mongodb 的数据的时候直接,使用 pymongo 从非关系型数据库中读取数据,将数据转换成列表,在使用

import pandas as pd

from utils.db_mongo import mongo_helper

v = mongo_helper.fetch_all("test")   # 调用已经封装好的模块将信息成功,返回列表
sv = pd.DataFrame(v) # 加载成为 pandas 对象;
print(sv.head())

3.5 数据信息的统计

本部分属于额外补充,因为导入数据完成之后,会直接将数据信息设置,进行一下简单的统计;

v = mongo_helper.fetch_all("test")
sv = pd.DataFrame(v)
print(sv.shape)    # 获取数据的行数和列数;
print(sv.info())   # 显示各列的数据类型以及是否包含空值;

4.数据清洗

数据清洗,是数据预处理中的一个步骤;pandas 数据处理主要包含缺失值的处理和异常值处理

4.1 空值的清洗

缺失值的处理:对待缺失值的处理一般有两种方法,分别是插值法删除法操作的类型也主要有两种,一种是有具体数值的,另一种是类别的离散值;

4.1.1 空值的删除

相关的函数

DataFrame.dropna(axis=0, how=\'any\', thresh=None, subset=None, inplace=False)

参数说明:

  • axis:默认为 0,表示逢空值剔除整行,如果设置参数 axis=1 表示逢空值去掉整列。
  • how:默认为 \'any\' 如果一行(或一列)里任何一个数据有出现 NA 就去掉整行,如果设置 how=\'all\' 一行(或列)都是 NA 才去掉这整行。
  • thresh:设置需要多少非空值的数据才可以保留下来的。
  • subset:设置想要检查的列。如果是多个列,可以使用列名的 list 作为参数。
  • inplace:如果设置 True,将计算得到的值直接覆盖之前的值并返回 None,修改的是源数据。

检查单元格是否为空isnull(),判断单元格是否为空;

4.1.2 空值的填充

使用较少,因为当数据量较大的时候删除一些空值数据并不影响具体的操作,当数据量较少的时候填充是非常不错的选择;

对于类别值或离散值,,我们将“NaN”视为一个类别。比如name列有"Tom"和“NaN”两个类别,pandas会自动将一列转化为两列,并且两列分别为“name_Tom”和"name_NaN"。并且转化为的两列中,每一行等于该列对应的类别的取1,否则取0。比如name_Tom列,只有第一行为1,其余行均为0,这里有点类似onehot编码。
这里用到get_dummies()函数,类似onehot编码。

inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)

按照上一行(下一行)进行数据的填充,参考文章:https://blog.csdn.net/weixin_46089741/article/details/122305108

# 上一行: 经常用在有分组信息的表里面
data = data.fillna(method=\'ffill\', inplace=True)

4.2 重复值的处理

判断重复行

# 重复值为 True
DataFrame.duplicated()

删除重复行

# 重复值的删除
DataFrame.drop_duplicates()

默认是,当这一行与前面某一行所有元素都重复才删除。否则,需要指定判断重复的标志列。默认保留第一行重复值,也可指定保留最后一行;

df.drop_duplicates([\'商品名称\'], keep=\'last\')
 
Out[2]: 
  商品名称  地区  销量
0  李老吉  北京  15
2  康帅傅  广州  28
3  娃啥啥  上海  13

4.3 经验异常值处理

经验指的是行业经验,即要结合具体业务。以气温为例子。放在全球来讲,气温最高也就 50 左右。那么可以简单认为超过 60 的气温数据就是异常。结合上一章讲的数据过滤即可实现。

df
 
Out[1]: 
    城市  温度
0   北京  -5
1   上海   5
2   广州  15
3  基加利  75
 
# 只选择温度小于60的
df[df[\'温度\']<60]
 
Out[2]: 
   城市  温度
0  北京  -5
1  上海   5
2  广州  15

5.数据的类型转换与简单计算

dataframe.info()     # 查看数据的类型;与值的描述;
dataframe.dtypes     # 查看数据类型;

这里不在对数据类型进行介绍;只对常见的数据类型之间的转换进行记录

5.1 读取数据时直接指定数据类型

import pandas as pd

df = pd.read_excel(\'数据类型转换案例数据.xlsx\',
                   dtype=
                       \'国家\':\'string\',
                       \'向往度\':\'Int64\'
                   
                 )

使用astype()函数

df.受欢迎度.astype(\'float\')

5.2 日期类型的转换

pd.to_datetime(s, unit=\'ns\')      # 常见的情况
pd.to_datetime(s, format=\'%Y%m%d\', errors=\'coerce\')
# 时间差类型
pd.to_timedelta转化为时间差类型
In [23]: import numpy as np

In [24]: pd.to_timedelta(np.arange(5), unit=\'d\')
Out[24]: TimedeltaIndex([\'0 days\', \'1 days\', \'2 days\', \'3 days\', \'4 days\'], dtype=\'timedelta64[ns]\', freq=None)

In [25]: pd.to_timedelta(\'1 days 06:05:01.00003\')
Out[25]: Timedelta(\'1 days 06:05:01.000030\')

In [26]: pd.to_timedelta([\'1 days 06:05:01.00003\', \'15.5us\', \'nan\'])
Out[26]: TimedeltaIndex([\'1 days 06:05:01.000030\', \'0 days 00:00:00.000015500\', NaT], dtype=\'timedelta64[ns]\', freq=None)

说明:时间字符串,日期和时间是有一个空格的2022-12-31 18.01.02,没有空格是无法转换的;

5.3 智能转换数据类型

convert_dtypes方法可以用来进行比较智能的数据类型转化,请看

6.数据的筛选

数据筛选是读取和预处理之后,

"""参考文章: https://blog.csdn.net/joker_zsl/article/details/119874694
"""
import pandas as pd

df = pd.DataFrame(\'key\': [\'A\', \'B\', \'C\', \'A\', \'B\', \'C\', \'A\', \'B\', \'C\'], \'data\': [0, 5, 10, 5, 10, 15, 10, 15, 20])


def print_line():
    print("---------------------------------------------------------------------")


# 简单条件筛选; 类似于 SQL 的 where key = \'A\'
print(df[df[\'key\'] == \'A\'])
"""
  key  data
0   A     0
3   A     5
6   A    10
"""
print_line()
# 复杂条件筛选, 选出大于均值的数据, 在将取到的值按照指定列进行升序排序;
print(df[df[\'data\'] > df[\'data\'].mean()].sort_values(by=\'data\', ascending=False))
"""
  key  data
8   C    20
5   C    15
7   B    15
"""

print_line()
"""
loc : 通过索引 index 中取出具体的值;
iloc : 通过行号去数据;
参考文章: https://blog.csdn.net/weixin_44852067/article/details/122301685
"""
print(df.loc[1])  # 取出索引为 1 的数据;
print(df.iloc[0])  # 第 0 行数据;
# 取出 A列所有的行

"""
key     B
data    5
Name: 1, dtype: object
key     A
data    0
Name: 0, dtype: object
"""
print_line()
print(df.loc[:, [\'key\', \'data\']])
"""
  key  data
0   A     0
1   B     5
2   C    10
3   A     5
4   B    10
5   C    15
6   A    10
7   B    15
8   C    20
"""
print_line()
# 按照条件提取
print(df.loc[(df[\'data\'] > df[\'data\'].mean()), [\'key\']])
"""
  key
5   C
7   B
8   C
"""
print_line()
# isin 函数使用包含筛选筛选
print(df.loc[df[\'data\'].isin([0, 5, 15]), :])
"""
  key  data
0   A     0
1   B     5
3   A     5
5   C    15
7   B    15
"""
print_line()
# str.contains 字符串包含查询; 经常用在长字符串中;
print(df.loc[df[\'key\'].str.contains(\'A\'), :])
"""
  key  data
0   A     0
3   A     5
6   A    10
"""

print_line()
# where, 不满足条件的被赋值(默认赋空值)
cond = df[\'key\'] == \'A\'
print(df[\'key\'].where(cond, inplace=False))  # 赋值空
print(df[\'key\'].where(cond, other="Hello", inplace=False))  # 赋值 hello
"""
0      A
1    NaN
2    NaN
3      A
4    NaN
5    NaN
6      A
7    NaN
8    NaN
Name: key, dtype: object
0        A
1    Hello
2    Hello
3        A
4    Hello
5    Hello
6        A
7    Hello
8    Hello
Name: key, dtype: object

"""

print_line()
# query 查找
print(df.query(\'data > 10\'))  # 与最开使得 df[df[\'data\'] > 10] 相同
print(df.query(\'key.str.contains("A") & data > 5\'))
# 上面的 query 一般情况下都是可以用原生的函数进行还原;
print(df[(df[\'key\'].str.contains(\'A\')) & (df[\'data\'] > 5)])
"""
  key  data
5   C    15
7   B    15
8   C    20
  key  data
6   A    10
  key  data
6   A    10

"""
print_line()
# filter 过滤
"""
filter是另外一个独特的筛选功能。filter不筛选具体数据,而是筛选特定的行或列。它支持三种筛选方式:
    - items:固定列名

    - regex:正则表达式

    - like:以及模糊查询

axis:控制是行 index 或列 columns 的查询
"""
print(df.filter(items=[\'key\']))
print(df.filter(regex=\'e\', axis=1))  # 查找列
print(df.filter(regex=\'1\', axis=0))  # 查找行
# 模糊匹配
print(df.filter(like=\'a\', axis=1))
"""
  key
0   A
1   B
2   C
3   A
4   B
5   C
6   A
7   B
8   C
  key
0   A
1   B
2   C
3   A
4   B
5   C
6   A
7   B
8   C
  key  data
1   B     5
   data
0     0
1     5
2    10
3     5
4    10
5    15
6    10
7    15
8    20
"""

print_line()
"""
any方法意思是,如果至少有一个值为True结果便为True,all需要所有值为True结果才为True,比如下面这样。
any和all一般是需要和其它操作配合使用的,比如查看每列的空值情况。
"""

print(df[\'key\'].any())
print(df.isnull())  # 检查是否存在空值,存在返回 True
print(df.isnull().any(axis=0))  #
print(df.isnull().any(axis=1).sum())  # 查看空值的函数
"""
---------------------------------------------------------------------
True
     key   data
0  False  False
1  False  False
2  False  False
3  False  False
4  False  False
5  False  False
6  False  False
7  False  False
8  False  False
key     False
data    False
dtype: bool
0
"""

8.数据分析常用函数与功能

pandas 可以完成数据统计分析的基础部分,因此也是必不可少的利器;

8.1 pandas 分组聚合

说明:当数据源是mysql等关系数据库的时候,可以使用group by进行数据的分组聚合,效果依旧很好,pandas 最长用在 csv 等数据集中;

pandas 分组聚合是简单的统计分析的利器,但是其中的函数特别容易混乱,不需要记住每个函数的信息,只需要知道逻辑是分组后的操作,就可以根据查询,或者自定义操作后的函数信息;

参考文章:https://blog.csdn.net/fullbug/article/details/122892358

# 构建数据数据集, 通过简单的数据集进行分析,可以更好的剖析每个函数的功能;
df=pd.DataFrame(\'key\':[\'A\',\'B\',\'C\',\'A\',\'B\',\'C\',\'A\',\'B\',\'C\'],\'data\':[0,5,10,5,10,15,10,15,20])
df.head()

8.1.1 数据分组

# 按照 key 进行分组,分组后没一个类别中相当于有一个字表
pd.DataFrame(df.groupby([\'key\']))
# 查看字表的信息;
pd.DataFrame(df.groupby([\'key\']))[1][0]

虽然这种方法可以查看到分组后的字表,但是不到万不得已,不要使用这种表嵌套的形式,该种方式不太符合展示与后期的程序处理,可以在中间过程试用一下作为中间数据的处理桥梁,但是步骤依旧繁琐,因此最好减少使用;

8.1.2 数据聚合

# 此处重新构建数据集,因为实际的数据分析中往往都是多列的数据信息
df=pd.DataFrame(
    \'key\':[\'A\',\'B\',\'C\',\'A\',\'B\',\'C\',\'A\',\'B\',\'C\'],
    \'data\':[0,5,10,5,10,15,10,15,20],
    \'v\':[0,3,9,3,9,12,15,9,18])
df

分组求和

# 求和,使用分组聚合之后,是对数据中得每一列都进行了聚合
v = df.groupby([\'key\']).sum()
v
# 只对某一列进行求和
sv = df.groupby([\'key\'])[\'v\'].sum()
sv

# 其他的常见聚合函数
# 每一列求均值,求取单独一列的时候可以像上一步一样进行选取
df.groupby([\'key\']).mean()
df.groupby([\'key\']).max()
df.groupby([\'key\']).min()

其他常见的函数信息

函数名 描述
count 分组中非NA值的数量
sum 非NA值的和
mean 非NA值的平均值
median 非NA值的中位数
std, var 标准差和方差
min, max 非NA的最小值,最大值
prod 非NA值的乘积
first, last 非NA值的第一个,最后一个

更多的分组后的操作

使用自定义的聚合函数

# 求极差函数:
def peak_to_peak(arr: pd.Series):
    return arr.max() - arr.min()
# 执行自定义的函数信息;
df.groupby([\'key\']).agg(peak_to_peak)

分组后的过滤

def filter_sum(arr):
    if arr[\'data\'].sum() > 20:
        return True  # 返回 true 
    else:
        return False # 不满足,被过滤


df.groupby(\'key\').filter(filter_sum)

8.2 one-hot 编码

import pandas as pd

# 构建数据集
df = pd.DataFrame([
    [\'green\', \'A\', 2],
    [\'red\', \'B\', 3],
    [\'blue\', \'A\', 2],
])
# 重新命名列名
df.columns = [\'color\', \'class\', \'num\']
print(df)
# 进行 one-hot 编码
print(pd.get_dummies(df))

8.3 apply() 的使用

参考文章:https://blog.csdn.net/weixin_44852067/article/details/122364306

Pandas 的apply()方法是用来调用一个函数(python method),让自定义的函数对数据进行批处理。Pandas 的很多对象都可以使用 apply() 来调用函数,如 Dataframe、Series、分组对象、各种时间序列等。

# apply(函数), 最常见的是内部传入的是匿名函数信息;
import pandas as pd
import numpy as np

df = pd.DataFrame([[4, 9]] * 3, columns=[\'A\', \'B\'])
print(df)

# pandas 使用 numpy 的函数;
print(df.apply(np.sqrt))  # 求开方后的值
print(df.apply(np.sum, axis=1))  # axis=1 横向,axis=0 纵向;
# 使用匿名函数;
print(df.apply(lambda x: x + 2))  # 每一个值加 2


# 使用自定义的函数
def square(x):
    return x ** 2


print(df.apply(square))

"""
   A  B
0  4  9
1  4  9
2  4  9
     A    B
0  2.0  3.0
1  2.0  3.0
2  2.0  3.0
0    13
1    13
2    13
dtype: int64
   A   B
0  6  11
1  6  11
2  6  11
    A   B
0  16  81
1  16  81
2  16  81
"""

8.4 导出为 python数据类型

# 经常用在使用 python 原生数据中,常见的是 Pyecharts 的可视化操作中;
print(df[\'A\'].tolist())
print(df[\'A\'].to_dict())

8.5 pandas 计算分位数

import pandas as pd

df = pd.DataFrame(\'a\': [1, 2, 3], \'b\': [4, 5, 6], \'c\': [\'d\', \'e\', \'f\'])
print(df[\'a\'].quantile(0.25))

9.数据的合并与导出

数据的导出主要分为SQL的导出和csv文件的导出;当数据量不是特别巨大的时候 csv 文件是不错的选择,因为SQL导出的时候会将数据之间的相关的关联与约束全部取消掉;

9.1 表连接

表的连接分为横向和纵向两个方向;

9.1.1 横向连接

不到万不得已的情况下不要使用表的拼接;

# 只能实现两张表的合并,按照指定的列进行合并
import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.arange(12).reshape(3, 4), columns=[\'a\', \'b\', \'c\', \'d\'])
print(df1)
df2 = pd.DataFrame(\'b\': [1, 5], \'d\': [3, 7], \'a\': [0, 4])
print(df2)
# 横向连接重叠列自动
print("------------------")
print(pd.merge(df1, df2))  # 只会留下数据相同的列;
"""
   a  b   c   d
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11
   b  d  a
0  1  3  0
1  5  7  4
------------------
   a  b  c  d
0  0  1  2  3
1  4  5  6  7
"""

直接拼接

print(pd.concat([df1, df2], axis=1))
"""
    A   B   C   D   E   A   B   C   D   F
0  A0  B0  C0  D0  E0  A4  B4  C4  D4  F4
1  A1  B1  C1  D1  E1  A5  B5  C5  D5  F5
2  A2  B2  C2  D2  E2  A6  B6  C6  D6  F6
3  A3  B3  C3  D3  E3  A7  B7  C7  D7  F7
"""

concat 的函数模式较多不做过多的描述;

9.1.2 纵向连接

import pandas as pd


df1 = pd.DataFrame(\'A\': [\'A0\', \'A1\', \'A2\', \'A3\'],
                    \'B\': [\'B0\', \'B1\', \'B2\', \'B3\'],
                    \'C\': [\'C0\', \'C1\', \'C2\', \'C3\'],
                    \'D\': [\'D0\', \'D1\', \'D2\', \'D3\'],
                    \'E\': [\'E0\', \'E1\', \'E2\', \'E3\']
                    )
df2 = pd.DataFrame(\'A\': [\'A4\', \'A5\', \'A6\', \'A7\'],
                    \'B\': [\'B4\', \'B5\', \'B6\', \'B7\'],
                    \'C\': [\'C4\', \'C5\', \'C6\', \'C7\'],
                    \'D\': [\'D4\', \'D5\', \'D6\', \'D7\'],
                    \'F\': [\'F4\', \'F5\', \'F6\', \'F7\']
                    )
# 默认的concat,参数为axis=0、join=outer、ignore_index=False
print(pd.concat([df1, df2]))
"""
    A   B   C   D    E    F
0  A0  B0  C0  D0   E0  NaN
1  A1  B1  C1  D1   E1  NaN
2  A2  B2  C2  D2   E2  NaN
3  A3  B3  C3  D3   E3  NaN
0  A4  B4  C4  D4  NaN   F4
1  A5  B5  C5  D5  NaN   F5
2  A6  B6  C6  D6  NaN   F6
3  A7  B7  C7  D7  NaN   F7
"""

9.2 数据导出

# 导出到 csv
df.to_csv("data.csv", encoding="utf-8")
# 其他导出 json 文件的方法与之类似;

导出数据到数据库中

import pymysql
from sqlalchemy import create_engine
 
# 创建数据库引擎,传入uri规则的字符串
engine = create_engine(\'mysql+pymysql://root:chuanzhi@127.0.0.1:3306/python?charset=utf8\')
# 数据库中会创建对应的表, 但是对应之间关系没有,数据类型约束可能也没有
df.to_sql(\'tb_scientists\', engine, index=False, if_exists=\'append\')

继续努力,终成大器!

pandas常见函数详细使用

groupby函数

pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作,根据一个或多个键(可以是函数、数组、Series或DataFrame列名)拆分pandas对象,继而计算分组摘要统计,如计数、平均值、标准差,或用户自定义函数。

ipl_data = {Team: [Riders, Riders, Devils, Devils, Kings,
         kings, Kings, Kings, Riders, Royals, Royals, Riders],
         Rank: [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
         Year: [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
         Points:[876,789,863,673,741,812,756,788,694,701,804,690]}

按照Team进行分组,并计算Points列的平均值:我们可以先访问Points,并根据Team调用groupby:

grouped = df[Points].groupby(df[Team])
#等价于df[‘Points‘].groupby(df.Team) 以及 df[‘Points‘].groupby(df.Team.values)
print(grouped.groups)
grouped.mean()

输出:

技术图片
{Devils: Int64Index([2, 3], dtype=int64), Kings: Int64Index([4, 6, 7], dtype=int64), Riders: Int64Index([0, 1, 8, 11], dtype=int64), Royals: Int64Index([9, 10], dtype=int64), kings: Int64Index([5], dtype=int64)}

Team
Devils    768.000000
Kings     761.666667
Riders    762.250000
Royals    752.500000
kings     812.000000
Name: Points, dtype: float64
View Code

说明:数据(Series)根据分组键进行了聚合,产生了一个新的Series,其索引为Team列中的唯一值。

 

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

Pandas DataFrame 函数应用和映射

pandas索引的设置与修改

pandaspandas中的常见函数

轻松学习学 Pandas:17个函数操作可以这样学起来

举一反三-Pandas实现Hive中的窗口函数

Pandas数据探索分析,分享两个神器