Python 之 Pandas 处理字符串和apply() 函数、applymap() 函数、map() 函数详解

简介: Python 之 Pandas 处理字符串和apply() 函数、applymap() 函数、map() 函数详解

文章目录



一、处理字符串



  • 当我们遇到一个超级大的 DataFrame,里面有一列类型为字符串,要将每一行的字符串都用同一方式进行处理, 一般会想到遍历整合 DataFrame。
  • 但是如果直接这样做的话将会耗费很长时间,有时几个小时都处理不完。 因此我们将学习 pandas 快速处理字符串方法。



1. 向量化字符串操作简介


  • 量化操作简化了纯数值的数组操作语法,我们不需要再担心数组的长度或维度,只需要把中心放在操作上面。
  • 而对字符串的向量化需要工具包的支持,如 Numpy 就没办法直接对字符串进行向量化操作,只能通过繁琐的循环来实现。 Pandas 则可以很好的处理这类问题。



2. str 方法的简介


Python 会处理字符串起来会很容易,作为工具包的 Pandas 同样可以简单快速的处理字符串,几乎把 Python 内置的字符串方法都给复制过来了,这种方法就是 Pandas 内置的 str 方法。

通俗来说就可以将 series 和 index 对象中包含字符串的部分简单看作单个字符串处理,达到批量简单快速处理的目的,str 方法有如下函数可供我们使用。


函数 含义
lower() 将的字符串转换为小写
upper() 将的字符串转换为大写
len() 得出字符串的长度


strip() 去除字符串两边的空格(包含换行符)
split() 用指定的分割符分割字符串
cat(sep=“”) 用给定的分隔符连接字符串元素


contains(pattern) 如果子字符串包含在元素中,则为每个元素返回一个布尔值 True,否则为 False
replace(a,b) 将值 a 替换为值 b
count(pattern) 返回每个字符串元素出现的次数


startswith(pattern) 如果 Series 中的元素以指定的字符串开头,则返回 True
endswith(pattern) 如果 Series 中的元素以指定的字符串结尾,则返回 True


findall(pattern) 以列表的形式返出现的字符串
find(pattern) 返回字符串第一次出现的索引位置



  • 这里需要注意的是,上述所有字符串函数全部适用于 DataFrame 对象,同时也可以与 Python 内置的字符串函数一起使用,这些函数在处理 Series/DataFrame 对象的时候会自动忽略缺失值数据(NaN)。
  • 首先,我们导入需要的 numpy 和 pandas 库。
import pandas as pd
import numpy as np


  • 1) lower() 函数可以将的字符串转换为小写。
s = pd.Series(['C', 'Python', 'java', 'go', np.nan, '1125','javascript'])
s.str.lower()
0             c
1        python
2          java
3            go
4           NaN
5          1125
6    javascript
dtype: object



  • (2) upper() 将的字符串转换为大写。
s = pd.Series(['C', 'Python', 'java', 'go', np.nan, '1125','javascript'])
s.str.upper()
#0             C
#1        PYTHON
#2          JAVA
#3            GO
#4           NaN
#5          1125
#6    JAVASCRIPT
#dtype: object


  • (3) len() 得出字符串的长度。
s = pd.Series(['C', 'Python', 'java', 'go', np.nan, '1125','javascript'])
s.str.len()
#0     1.0
#1     6.0
#2     4.0
#3     2.0
#4     NaN
#5     4.0
#6    10.0
#dtype: float64



  • 4) strip() 去除字符串两边的空格(包含换行符)。
s = pd.Series(['C ', ' Python\t     \n', '    java     ', 'go\t', np.nan, '\t1125 ','\tjavascript'])
s_strip = s.str.strip(" ")
s_strip
#0                  C
#1    Python\t     \n
#2               java
#3               go\t
#4                NaN
#5             \t1125
#6       \tjavascript
#dtype: object



  • (5) split() 用指定的分割符分割字符串。
s = pd.Series(['Zhang hua',' Py thon\n','   java   ','go','11 25 ','javascript'])
print(s.str.split(" "))
#0          [Zhang, hua]
#1        [, Py, thon\n]
#2    [, , , java, , , ]
#3                  [go]
#4            [11, 25, ]
#5          [javascript]
#dtype: object


  • 如果不带参数,会先执行 strip(),再默认以空格分割。
print(s.str.split())
#0    [Zhang, hua]
#1      [Py, thon]
#2          [java]
#3            [go]
#4        [11, 25]
#5    [javascript]
#dtype: object



  • 我们也可以对 strip() 的参数进行设置。
print(s.str.strip().str.split(" "))
#0    [Zhang, hua]
#1      [Py, thon]
#2          [java]
#3            [go]
#4        [11, 25]
#5    [javascript]
#dtype: object


  • (6) cat(sep=“”) 用给定的分隔符连接字符串元素。
  • cat(sep=“”) 函数会自动忽略 NaN。
s = pd.Series(['C', 'Python', 'java', 'go', np.nan, '1125','javascript'])
s_cat = s.str.cat(sep="_")
s_cat
#'C_Python_java_go_1125_javascript'



  • (7) contains(pattern) 如果子字符串包含在元素中,则为每个元素返回一个布尔值 True,否则为 False。
  • 我们可以取出 s 中包含空格的元素。
s = pd.Series(['C ',' Python','java','go','1125 ','javascript'])
s.str.contains(" ")
#0     True
#1     True
#2    False
#3    False
#4     True
#5    False
#dtype: bool


  • 也可以将 True 返回原数据。
s[s.str.contains(" ")]
#0         C 
#1     Python
#4      1125 
#dtype: object


  • (8) replace(a,b) 将值 a 替换为值 b。
s =s = pd.Series(['C ',' Python','java','go','1125 ','javascript'])
s.str.replace("java","python")
#0              C 
#1          Python
#2          python
#3              go
#4           1125 
#5    pythonscript
#dtype: object



  • (9) count(pattern) 返回每个字符串元素出现的次数。
s = pd.Series(['C ','Python Python','Python','go','1125 ','javascript'])
s.str.count("Python")
#0    0
#1    2
#2    1
#3    0
#4    0
#5    0
#dtype: int64


(10) startswith(pattern) 如果 Series 中的元素以指定的字符串开头,则返回 True。

(11) endswith(pattern) 如果 Series 中的元素以指定的字符串结尾,则返回 True。

s = pd.Series(['C ',' Python','java','go','1125 ','javascript'])
print(s.str.startswith("j"))​
#0    False
#1    False
#2     True
#3    False
#4    False
#5     True
#dtype: bool


  • 12) repeat(value) 以指定的次数重复每个元素。
s = pd.Series(['C ',' Python','java','go','1125 ','javascript'])
print(s.str.repeat(3))
#0                            C C C 
#1              Python Python Python
#2                      javajavajava
#3                            gogogo
#4                   1125 1125 1125 
#5    javascriptjavascriptjavascript
#dtype: object


  • (13) find(pattern) 返回字符串第一次出现的索引位置。
  • 这里如果返回 -1 表示该字符串中没有出现指定的字符。
s = pd.Series(['C ',' Python','java','go','1125 ','javascript'])
print(s.str.find("a"))
#0   -1
#1   -1
#2    1
#3   -1
#4   -1
#5    1
#dtype: int64



  • (14) findall(pattern) 以列表的形式返出现的字符串。
s = pd.Series(['C ',' Python','java','go','1125 ','javascript'])
print(s.str.findall("a"))
#0        []
#1        []
#2    [a, a]
#3        []
#4        []
#5    [a, a]
#dtype: object


二、apply() 函数详解


在日常的数据处理中,经常会对一个 DataFrame 进行逐行、逐列和逐元素的操作,对应这些操作,Pandas 中的 map()、apply() 和 applymap() 可以解决绝大部分这样的数据处理需求。

三种方法的使用和区别如下:

apply() 函数应用在 DataFrame 的行或列中。

applymap() 函数应用在 DataFrame 的每个元素中。

map() 函数应用在单独一列(Series)的每个元素中。

前面也说了 apply() 函数是一般性的“拆分-应用-合并”方法。 apply() 将一个函数作用于 DataFrame 中的每个行或者列,它既可以得到一个经过广播的标量值,也可以得到一个相同大小的结果数组。

我们先来看下函数形式:

df.apply(func, axis=0, raw=False, result_type=None, args=(), **kwds)


  • 其参数含义如下:
  • func 表示函数应用于每一列或每一行。
  • axis 有 0 和 1 或者索引和列两种取值, 0 或“索引”表示将函数应用于每一列;1或“行”表示将函数应用于每一行。
  • 我们先生成初始数据,并将列标签设置为 A 和 B。
df = pd.DataFrame([[4, 9]] * 3, columns=['A', 'B'])
df
A B
0 4 9
1 4 9
2 4 9


  • 可以使用 apply() 函数对 A、B 两列进行求和(axis 参数默认为 0)。
df.apply(np.sum)
#A    12
#B    27
#dtype: int64


  • 我们将 axis 参数设置为 1,表示对每一行进行求和。
dfdf.apply(np.sum, axis=1)
#0    13
#1    13
#2    13
#dtype: int64


  • 或者我们使用 lambda 函数做简单的运算。
df.apply(lambda x: x + 1)
#   A  B
#0  5 10
#1  5 10
#2  5 10


  • 但是这样使用起来非常不方便,每次都要定义 lambda 函数。因此可以通过 def 定义一个函数,然后再调用该函数,在实际处理中都是定义自己所需要的函数完成操作:
def cal_result(df, x, y):
    df['C'] = (df['A'] + df['B']) * x
    df['D'] = (df['A'] + df['B']) * y
    return df


  • 我们使用自定义的函数进行计算,并生成 C、D 两列。
df.apply(cal_result, x=3, y=8, axis=1)
#   A B C D
#0  4 9 39  104
#1  4 9 39  104
#2  4 9 39  104


在这里我们先定义了一个 cal_result 函数,它的作用是计算 A,B 列和的 x 倍和 y 倍添加到 C,D 列中。

这里有三种方式可以完成参数的赋值:

(1) 第一种方式直接通过关键字参数赋值,指定参数的值。

(2) 第二种方式是使用 args 关键字参数传入一个包含参数的元组。

(3) 第三种方式传入通过 ** 传入包含参数和值的字典。

apply() 函数的使用是很灵活的,再举一个例子,配合 loc 方法我们能够在最后一行得到一个总和:

df.loc[2] = df.apply(np.sum)
df
#   A B
#0  4 9
#1  4 9
#2  12  27


三、applymap() 函数详解


  • applymap() 函数针对 DataFrame中 的元素进行操作,还是使用这个数据:df.applymap(func)
df
#   A B
#0  4 9
#1  4 9
#2  12  27


  • 们使用 lambda 函数将其变为浮点型。
df.applymap(lambda x: '%.2f'%x)
#      A     B
#0  4.00  9.00
#1  4.00  9.00
#2  4.00  9.00



  • 在这里可以看到 applymap() 函数操作的是其中的元素,并且是对整个 DataFrame 进行了格式化,我们也可以选择行或列中的元素。
  • 对行进行选取。
df[['A']]
#   A
#0  4
#1  4
#2  4


  • 对列进行选取。
df[['A']].applymap(lambda x: '%.2f'%x)
#      A
#0  4.00
#1  4.00
#2  4.00


  • 需要注意的是这里必须使用 df[[‘A’]] ,表示这是一个 DataFrame,而不是一个 Series,如果使用 df[‘A’] 就会报错。同样从行取元素也要将它先转成 DataFrame。
df['A'].applymap(lambda x: '%.2f'%x)  # 异常 
#---------------------------------------------------------------------------
#AttributeError                            Traceback (most recent call last)
#<ipython-input-11-585649caf30e> in <module>()
#----> 1 df['A'].applymap(lambda x: '%.2f'%x)  # 异常
#
#E:\Anaconda\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)
#   5139             if self._info_axis._can_hold_identifiers_and_holds_name(name):
#   5140                 return self[name]
#-> 5141             return object.__getattribute__(self, name)
#   5142 
#   5143     def __setattr__(self, name: str, value) -> None:
#
#AttributeError: 'Series' object has no attribute 'applymap'


  • 还需要注意 apply() 函数和 applymap() 函数的区别:
  • apply() 函数操作的是行或列的运算,而不是元素的运算,比如在这里使用格式化操作就会报错。
  • applymap() 函数操作的是元素,因此没有诸如 axis 这样的参数,它只接受函数传入


四、map() 函数详解

  • 如果对 applymap() 函数搞清楚了,那么map() 函数就很简单,说白了 map() 函数是应用在 Series 中的,还是举上面的例子。
df['A'].map(lambda x: '%.2f'%x)
#0    4.00
#1    4.00
#2    4.00
#Name: A, dtype: object



  • 需要注意的是,Series 没有 applymap() 函数。
df[['A']].applymap(lambda x: '%.2f'%x)
#---------------------------------------------------------------------------
#AttributeError                            Traceback (most recent call last)
#<ipython-input-11-585649caf30e> in <module>()
#----> 1 df[['A']].applymap(lambda x: '%.2f'%x)  # 异常
#
#E:\Anaconda\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)
#   5139             if self._info_axis._can_hold_identifiers_and_holds_name(name):
#   5140                 return self[name]
#-> 5141             return object.__getattribute__(self, name)
#   5142 
#   5143     def __setattr__(self, name: str, value) -> None:
#
#AttributeError: 'Series' object has no attribute 'applymap'





















































相关文章
|
1月前
|
机器学习/深度学习 数据可视化 搜索推荐
Python在社交媒体分析中扮演关键角色,借助Pandas、NumPy、Matplotlib等工具处理、可视化数据及进行机器学习。
【7月更文挑战第5天】Python在社交媒体分析中扮演关键角色,借助Pandas、NumPy、Matplotlib等工具处理、可视化数据及进行机器学习。流程包括数据获取、预处理、探索、模型选择、评估与优化,以及结果可视化。示例展示了用户行为、话题趋势和用户画像分析。Python的丰富生态使得社交媒体洞察变得高效。通过学习和实践,可以提升社交媒体分析能力。
51 1
|
1月前
|
数据挖掘 Python
【Python】已解决:Python pandas读取Excel表格某些数值字段结果为NaN问题
【Python】已解决:Python pandas读取Excel表格某些数值字段结果为NaN问题
67 0
|
17天前
【Pandas+Python】初始化一个全零的Dataframe
初始化一个100*3的0矩阵,变为Dataframe类型,并为每列赋值一个属性。
13 2
|
1月前
|
SQL 并行计算 API
Dask是一个用于并行计算的Python库,它提供了类似于Pandas和NumPy的API,但能够在大型数据集上进行并行计算。
Dask是一个用于并行计算的Python库,它提供了类似于Pandas和NumPy的API,但能够在大型数据集上进行并行计算。
|
13天前
|
分布式计算 Python
【python笔记】高阶函数map、filter、reduce
【python笔记】高阶函数map、filter、reduce
|
1月前
|
机器学习/深度学习 数据采集 数据挖掘
解锁 Python 数据分析新境界:Pandas 与 NumPy 高级技巧深度剖析
【7月更文挑战第12天】Python的Pandas和NumPy库助力高效数据处理。Pandas用于数据清洗,如填充缺失值和转换类型;NumPy则擅长数组运算,如元素级加法和矩阵乘法。结合两者,可做复杂数据分析和特征工程,如产品平均销售额计算及销售额标准化。Pandas的时间序列功能,如移动平均计算,进一步增强分析能力。掌握这两者高级技巧,能提升数据分析质量和效率。
32 4
|
1月前
|
数据采集 机器学习/深度学习 数据可视化
了解数据科学面试中的Python数据分析重点,包括Pandas(DataFrame)、NumPy(ndarray)和Matplotlib(图表绘制)。
【7月更文挑战第5天】了解数据科学面试中的Python数据分析重点,包括Pandas(DataFrame)、NumPy(ndarray)和Matplotlib(图表绘制)。数据预处理涉及缺失值(dropna(), fillna())和异常值处理。使用describe()进行统计分析,通过Matplotlib和Seaborn绘图。回归和分类分析用到Scikit-learn,如LinearRegression和RandomForestClassifier。
50 3
|
2月前
|
Python
Python中的Map Function
Python中的Map Function
|
2月前
|
Python
在Python中,`map()`, `filter()` 和 `reduce()` 是函数式编程中的三个核心高阶函数。
【6月更文挑战第24天】Python的`map()`应用函数到序列元素,返回新序列;`filter()`筛选满足条件的元素,生成新序列;`reduce()`累计操作序列元素,返回单一结果。
28 3
|
2月前
|
数据采集 机器学习/深度学习 数据可视化
利用Python和Pandas库构建高效的数据分析流程
在数据驱动的时代,数据分析已成为企业决策的关键环节。本文介绍如何利用Python编程语言及其强大的数据分析库Pandas,构建一套高效且可扩展的数据分析流程。与常规的数据分析流程不同,本文不仅涵盖数据加载、清洗、转换等基础步骤,还强调数据可视化、模型探索与评估等高级分析技巧,并通过实际案例展示如何在Python中实现这些步骤,为数据分析师提供一套完整的数据分析解决方案。