当前位置: 首页 > 后端技术 > Python

Pandas中高效的选择和替换操作总结

时间:2023-03-25 22:46:26 Python

作为数据科学家,使用正确的工具和技术来充分利用数据非常重要。Pandas是数据处理、分析和可视化的重要工具。有效地使用Pandas可能具有挑战性。从使用矢量化操作到利用内置函数,这些最佳实践可以帮助数据科学家使用Pandas快速准确地分析和可视化数据。在本文中,我们将关注两个最常在DataFrame上执行的最常见任务,尤其是在数据科学项目的数据操作阶段。这两个任务是高效地选择特定和随机的行和列,以及使用replace()函数将一个或多个值替换为列表和字典。在本文中,我们将使用以下数据集:扑克游戏数据集婴儿名字数据集我们将使用的第一个数据集是扑克游戏数据集,如下所示。poker_data=pd.read_csv('poker_hand.csv')poker_data.head()在每一轮中,每个玩家手上有五张牌,每张牌有一种花色:红心、方块、梅花或黑桃,其数量,不等从1到13。数据集包含一个人可以拥有的五张卡片的所有可能组合。Sn:第n张牌的符号,其中:1(红心),2(方块),3(梅花),4(黑桃)Rn:第n张牌的牌位,其中:1(王牌),2-10,11(J),12(Q),13(K)第二个数据集是流行的婴儿名字数据集,其中包括2011年到2016年最流行的新生儿名字:names=pd.read_csv('Popular_Baby_Names.csv')names.head()该数据集还包括按年份、性别和种族划分的美国最受欢迎的名字。例如,2011年,Chloe这个名字在所有亚裔和太平洋岛民女孩中排名第二。接下来,我们进入正题。为什么我们需要高效的代码?高效代码是指执行速度更快、计算能力更低的代码。在本文中,我们将使用time()函数来测量计算时间。我们通过获取执行前后的时间,然后计算差值来获取代码的执行时间。下面是一个简单的例子:importtime#记录执行前的时间start_time=time.time()#执行操作result=5+2#记录执行后的时间end_time=time.time()print("结果计算在{}秒内".format(end_time-start_time))让我们看一个提高代码运行时间并降低计算时间复杂度的例子:我们将计算每个数字的平方,从0到100万。首先,我们将使用列表理解来执行此操作,然后使用for循环重复相同的过程。首先使用列表理解:#usingListcomprehensionlist_comp_start_time=time.time()result=[i*iforiinrange(0,1000000)]list_comp_end_time=time.time()print("Timeusingthelist_comprehension:{}sec".format(list_comp_end_time-list_comp_start_time))使用for循环做同样的事情:#使用For循环for_loop_start_time=time.time()result=[]foriinrange(0,1000000):result.append(i*i)for_loop_end_time=time.time()print("timeusingtheforloop:{}sec".format(for_loop_end_time-for_loop_start_time))可以看到它们之间有很大的区别,我们可以用百分比来计算它们的区别between:list_comp_time=list_comp_end_time-list_comp_start_timefor_loop_time=for_loop_end_time-for_loop_start_timeprint("时间差:{}%".format((for_loop_time-list_comp_time)/list_comp_time*100))可以看到只是用了不同的方法,但是有执行效率差别很大。使用.iloc[]和.loc[]选择行和列这里我们描述了如何使用.iloc[]和.loc[]pandas函数从数据中有效地定位和选择行。我们将使用iloc[]作为索引号定位器,使用loc[]作为索引名称定位器。在下面的示例中,我们选择扑克数据集的前500行。首先使用.loc[]函数,然后使用.iloc[]函数。rows=range(0,500)#使用.loc[]选择行的时间loc_start_time=time.time()poker_data.loc[rows]loc_end_time=time.time()print("Timeusing.loc[]:{}sec".format(loc_end_time-loc_start_time))rows=range(0,500)#Timeselectingrowsusing.iloc[]iloc_start_time=time.time()poker_data.iloc[rows]iloc_end_time=time.time()print("Time使用.iloc[]:{}sec".format(iloc_end_time-iloc_start_time))loc_comp_time=loc_end_time-loc_start_timeiloc_comp_time=iloc_end_time-iloc_start_timeprint("时间差:{}%".format((loc_comp_time-iloc_comp_time)/*iloc_comp_time100))尽管两种方法的使用方式相同,但iloc[]的执行速度比loc[]快近70%。这是因为.iloc[]函数利用了索引的顺序,索引已经排序,因此速度更快。我们还可以使用它们来选择列,而不仅仅是行。在下一个示例中,我们将使用这两种方法选择前三列。iloc_start_time=time.time()poker_data.iloc[:,:3]iloc_end_time=time.time()print("Timeusing.iloc[]:{}sec".format(iloc_end_time-iloc_start_time))names_start_time=time.time()poker_data[['S1','R1','S2']]names_end_time=time.time()print("Timeusingselectionbyname:{}sec".format(names_end_time-names_start_time))loc_comp_time=names_end_time-names_start_timeiloc_comp_time=iloc_end_time-iloc_start_timeprint("Differenceintime:{}%".format((loc_comp_time-iloc_comp_time)/loc_comp_time*100))你可以看到使用.iloc[]进行列索引仍然快了80%。所以最好使用.iloc[],因为它更快,除非使用loc[]按名称选择某些列更容易。替换DF中的值替换DataFrame中的值是一项非常重要的任务,尤其是在数据清理阶段。让我们看一下我们之前加载的婴儿名字数据集:首先看性别列:names['Gender'].unique()我们可以看到女性由大写和小写两个值表示。这在真实数据中很常见,但是对于我们来说我们只是需要一个统一的表示,所以我们需要将其中一个值替换为另一个值。这里有两种做法,第一种是简单定义我们要替换的值,然后是我们要替换成什么。如下代码所示:"Replacevaluesusing.loc[]:{}sec".format(pandas_time))第二种方法是使用pandas内置函数.replace()如下:start_time=time.time()names['Gender'].replace('female','FEMALE',inplace=True)end_time=time.time()replace_time=end_time-start_timeprint("Timeusingreplace():{}sec".format(replace_time))可以是可见,内置函数比使用.loc()方法查找值的行和列索引并替换它快157%。print('Thedifference:{}%'.format((pandas_time-replace_time)/replace_time*100))我们也可以使用列表来替换多个值。例如,将所有WHITENON-HISPANIC或WHITENON-HISP更改为WNH。这里我们使用.loc[]函数和'or'语句来定位我们正在寻找的种族。然后做代入赋值。start_time=time.time()names['Ethnicity'].loc[(names["Ethnicity"]=='WHITENONHISPANIC')|(names["Ethnicity"]=='WHITENONHISP')]='WNH'end_time=time.time()pandas_time=end_time-start_timeprint("上述操作的结果以%s秒计算"%(pandas_time))或使用pandas内置的.replace()函数执行相同的操作,如下所示:start_time=time.time()names['Ethnicity'].replace(['WHITENONHISPANIC','WHITENONHISP'],'WNH',inplace=True)end_time=time.time()replace_time=end_time-start_timeprint("Timeusing.replace():{}sec".format(replace_time))我们可以再次看到使用.replace()方法比使用.loc[]方法快得多。为了更好地了解它有多快,让我们运行以下代码:print('Thedifference:{}%'.format((pandas_time-replace_time)/replace_time*100)).replace()方法比使用更快.loc[]方法快了87%。如果数据量很大,需要大量清洗,会有效减少数据清洗的计算时间,让pandas代码更快。最后,我们还可以使用字典来替换DataFrame中的单个值和多个值。如果您想在一个命令中使用多个替换函数,这将很有用。我们将使用字典将每个男性性别替换为BOY,将每个女性性别替换为GIRL。names=pd.read_csv('Popular_Baby_Names.csv')start_time=time.time()names['Gender'].replace({'MALE':'BOY','FEMALE':'GIRL','female':'girl'},inplace=True)end_time=time.time()dict_time=end_time-start_timeprint("Timeusing.replace()withdictionary:{}sec".format(dict_time))names=pd.read_csv('Popular_Baby_Names.csv')start_time=time.time()names['Gender'].replace('MALE','BOY',inplace=True)names['Gender'].replace('FEMALE','GIRL',inplace=True)names['Gender'].replace('female','girl',inplace=True)end_time=time.time()list_time=end_time-start_timeprint("Timeusingmultiple.replace():{}秒".format(list_time))比较这两种方法,我们可以看到使用字典的运行速度提高了大约22%。使用字典替换多个不同列上的相同值。我们想将所有种族分为三大类:黑人、亚洲人和白人。这里的代码也很简单。使用嵌套字典:外键是我们要替换值的列名。该值是另一个字典,其中键是要替换的字典。start_time=time.time()names.replace({'Ethnicity':{'ASIANANDPACI':'ASIAN','ASIANANDPACIFICISLANDER':'ASIAN','BLACKNONHISPANIC':'BLACK','BLACKNONHISP':'BLACK','WHITENONHISPANIC':'WHITE','WHITENONHISP':'WHITE'}})print("Timeusing.replace()withdictionary:{}sec".format(time.time()-start_time))总结使用.iloc[]函数可以更快地选择行和列,它比loc[]更快,但是loc[]提供了一些更方便的功能,如果速度不是优先考虑的或者如果实现iloc[]的比较麻烦,那就考虑用loc[]。使用内置的replace()函数比使用传统方法快得多。使用python字典替换多个值比使用列表更快。本文代码:https://avoid.overfit.cn/post/2c0d17effb934e6da75c33e6402029c6作者:YoussefHosni