使用apply函数与字符匹配进行数据分析
1、apply函数使用
DataFrame.apply(self, func, axis=0, raw=False, result_type=None, args=(), **kwds
func:代表的是传入的函数或lambda表达式;
axis:可提供的参数有两个,该参数默认为0(即列值)
0或者index,表示函数处理的是每一列;
1或columns,表示处理的是每一行;
raws:bool类型,默认为False;
False,表示把每一行或列作为Series传入函数中;
True:表示接受的是ndarray数据类型;
apply() 最后的是经过函数处理,数据以 Series 或 DataFrame 格式返回
下面做个简单示例 :
import pandas as pd
import numpy as np
df = pd.DataFrame([[4,9]] * 3,columns = ['a','b'])
df
apply函数应用示例:
#对每个元素应用sqrt
df.apply(np.sqrt)
#默认为0,对列值进行mean计算
df.apply(np.mean)
2、字符串匹配
字符串匹配有多种方式,其中
str.endswith():以特定字符串结尾
str.startswith():以特定的字符串开头
str.match():匹配正则表达式模式,对应于re.match(),并确定字符串的开头是否与模式匹配。如果不是一开始就为False
具体详情可以参照pandas字符串匹配方法
list = re.findall(regex,string,flag)
用于非重复的搜索某字符串中一个正则表达式模式出现的情况.
findall总返回一个列表,如果没有找到则返回空
如果正则表达式中含有一个子组,则返回的列表中的各项是匹配到的字符串的子组内容,整体匹配到几处就有几个子组内容
import re
string0 = 'abcdefgh'
list0 = re.findall('ab',string0)
print(list0)
# ['ab']输出
string1 = 'abcdefghab'
list1 = re.findall('ab',string1)
print(list1)
# ['ab', 'ab']输出
string2 = 'abcdefghab'
list2 = re.findall('(ab)cd',string2)#包含子组的搜索会返回更复杂的一个列表
print(list2)
# ['ab']#输出
string3 = 'abefghabef'
list3 = re.findall('(ab)ef',string3)
print(list3)#一个字组匹配到两处 只显示子组内容
# ['ab', 'ab']
3、数据分析实战
下面进行具体的实战分析,首先,既然是进行数据分析,就需要有一定的数据对象,所以先获取数据,使用pandas的read_csv函数,不过这里我讲读取数据的操作封装成了函数,下面进行代码展示:
pd.set_option('display.width',None)#这里可以去掉终端输出显示的省略号
def get_data(filepath):#filepath是我们的文件路径名
if filepath == " ":
#print("您输入的文件路径为空")
return
else:
data = pd.read_csv(filepath)
return data
#下面是对于函数的调用,并赋值给data
file_path = 'Data_analysis/detect_dirty_data/dirty_beer.csv'
data = get_data(file_path)
从上面的代码中,我们就可以得到一个两千多行的数据,并且观察到数据中ounces的属性列有不符合pattern的数据出现,比如下面所示:
我们的主要目标就是将上面带有.0 oz的值更改为正确的,也就是将.0 oz去除。既然要去掉形如方框中的字符,那我们首先要找到那些属性列值是和上面匹配的,也就是进行字符匹配。
def chance_data(whole_row):
a_data = whole_row['ounces']#whole_row是一整行数据,这里取ounces属性值
if re.search(r'\.0 oz', a_data):#如果数据是带有.0 oz
new_data = re.findall(r'\d+\.\d+', a_data)[0]#找到所有匹配的字符串,并赋值给new_data
whole_row['ounces'] = new_data
return whole_row
上面我们对数据进行字符串匹配,可以看到我们取到的是数据的一个属性值,如果符合匹配规则,我们就是用findall将.0 oz抛弃,只取形如12.0的值。可以看到findall得到的是一个列表的类型,所以我们取第一个元素就可以得到想要的结果。
字符匹配的目标我们就已经完成了,下面就是apply函数的应用了。
data1 = data.apply(lambda x: chance_data(x) , axis=1)
上面axis = 1表示取的dataframe的一行值,apply应用就是每次传值一行值给函数chance_data(x),x就是我们data的一行值,随后使用上面的chance_data(whole_row)函数对一行值进行处理。
最后,附上源码,有需要的小伙伴可以自取。
from numpy.lib.function_base import average
from numpy.lib.utils import who
import pandas as pd
import numpy as np
import re
pd.set_option('display.width',None)
def get_data(filepath):
if filepath == " ":
#print("您输入的文件路径为空")
return
else:
data = pd.read_csv(filepath)
return data
#对一行值进行处理
def chance_data(whole_row):
a_data = whole_row['ounces']
if re.search(r'\.0 oz', a_data):
new_data = re.findall(r'\d+\.\d+', a_data)[0]
whole_row['ounces'] = new_data
return whole_row
file_path = 'Data_analysis/detect_dirty_data/dirty_beer.csv'#文件路径
data = get_data(file_path)#得到数据
# print(type(data))
# print(type(data['ounces']))
data1 = data.apply(lambda x: chance_data(x) , axis=1)#apply函数应用对数据进行处理
print(type(data1))
print(data1)
今天的学习分享就到这里了,小张同学在一步一步记录自己的学习,希望在自己加深理解的同时也能够帮助正在学习数据分析的小伙伴们!!!最后,既然看到这里了,那就点个赞再划走喽。(嘿嘿)