关于人工智能:Pandas中高效的选择和替换操作总结

5次阅读

共计 6021 个字符,预计需要花费 16 分钟才能阅读完成。

作为数据科学家,应用正确的工具和技术来最大限度地利用数据是很重要的。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() 函数来测量计算工夫,咱们通过在执行前和执行后获取工夫,而后计算其差值取得代码的执行工夫。上面是一个简略的例子:

 import time
 # record time before execution
 start_time = time.time()
 # execute operation
 result = 5 + 2
 # record time after execution
 end_time = time.time()
 print("Result calculated in {} sec".format(end_time - start_time))

让咱们看一个进步代码运行工夫并升高计算工夫复杂度的示例: 咱们将计算每个数字的平方,从 0 到 100 万。首先,咱们将应用列表推导式来执行此操作,而后应用 for 循环反复雷同的过程。

首先应用列表推导式:

 #using List comprehension 
 
 list_comp_start_time = time.time()
 result = [i*i for i in range(0,1000000)]
 list_comp_end_time = time.time()
 print("Time using the list_comprehension: {} sec".format(list_comp_end_time -
 list_comp_start_time))

应用 for 循环来执行雷同的操作:

 # Using For loop
 
 for_loop_start_time= time.time()
 result=[]
 for i in range(0,1000000):
   result.append(i*i)
 for_loop_end_time= time.time()
 print("Time using the for loop: {} sec".format(for_loop_end_time - for_loop_start_time))

能够看到它们之间有很大的差别,咱们能够用百分比来计算它们之间的差别:

 list_comp_time = list_comp_end_time - list_comp_start_time
 for_loop_time = for_loop_end_time - for_loop_start_time
 print("Difference in time: {} %".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)
 # Time selecting rows using .loc[]
 loc_start_time = time.time()
 poker_data.loc[rows]
 loc_end_time = time.time()
 print("Time using .loc[] : {} sec".format(loc_end_time - loc_start_time))

 rows = range(0, 500)
 # Time selecting rows using .iloc[]
 iloc_start_time = time.time()
 poker_data.iloc[rows]
 iloc_end_time = time.time()
 print("Time using .iloc[]: {} sec".format(iloc_end_time - iloc_start_time))

 loc_comp_time = loc_end_time - loc_start_time
 iloc_comp_time = iloc_end_time - iloc_start_time
 print("Difference in time: {} %".format((loc_comp_time - iloc_comp_time)/
 iloc_comp_time*100))

尽管这两个办法应用的形式是雷同的,但 iloc[] 的执行速度比 loc[] 快近 70%。这是因为.iloc[] 函数利用了索引的程序,索引曾经排序因而速度更快。

咱们还能够应用它们来抉择列,而不仅仅是行。在下一个示例中,咱们将应用这两种办法抉择前三列。

 iloc_start_time = time.time()
 poker_data.iloc[:,:3]
 iloc_end_time = time.time()
 print("Time using .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("Time using selection by name: {} sec".format(names_end_time - names_start_time))

 loc_comp_time = names_end_time - names_start_time
 iloc_comp_time = iloc_end_time - iloc_start_time
 print("Difference in time: {} %".format((loc_comp_time - iloc_comp_time)/
 loc_comp_time*100))

能够看到,应用.iloc[] 进行列索引依然要快 80%。所以最好应用.iloc[],因为它更快,除非应用 loc[] 更容易按名称抉择某些列。

替换 DF 中的值

替换 DataFrame 中的值是一项十分重要的工作,特地是在数据清理阶段。

让咱们来看看之前加载的婴儿名字数据集:

首先看看性别列:

 names['Gender'].unique()

咱们能够看到,女性用大写和小写两个值示意。这在理论数据中十分常见,然而对于咱们来说只须要一个对立的示意就能够了,所以咱们须要将其中一个值替换为另一个值。这里有两种办法,第一种是简略地定义咱们想要替换的值,而后咱们想用什么替换它们。如上面的代码所示:

 start_time = time.time()
 names['Gender'].loc[names.Gender=='female'] = 'FEMALE'
 end_time = time.time()
 
 pandas_time = end_time - start_time
 print("Replace values using .loc[]: {} sec".format(pandas_time))

第二种办法是应用 panda 的内置函数.replace(),如下所示:

 start_time = time.time()
 names['Gender'].replace('female', 'FEMALE', inplace=True)
 end_time = time.time()
 replace_time = end_time - start_time
 
 print("Time using replace(): {} sec".format(replace_time))

能够看到,与应用.loc() 办法查找值的行和列索引并替换它相比,内置函数的快了 157%。

 print('The differnce: {} %'.format((pandas_time- replace_time)/replace_time*100))

咱们还能够应用列表替换多个值。比如说将所有 WHITE NON-HISPANIC 或 WHITE NON-HISP 都改为 WNH。这里咱们应用.loc[] 函数和 ’ or ‘ 语句定位咱们正在寻找的种族。而后进行替换赋值。

 start_time = time.time()
 
 names['Ethnicity'].loc[(names["Ethnicity"] == 'WHITE NON HISPANIC') |
 (names["Ethnicity"] == 'WHITE NON HISP')] = 'WNH'
 
 end_time = time.time()
 pandas_time= end_time - start_time
 print("Results from the above operation calculated in %s seconds" %(pandas_time))

或者应用 pandas 内置.replace() 函数执行雷同的操作,如下所示:

 start_time = time.time()
 names['Ethnicity'].replace(['WHITE NON HISPANIC','WHITE NON HISP'],
 'WNH', inplace=True)
 
 end_time = time.time()
 replace_time = end_time - start_time
 
 print("Time using .replace(): {} sec".format(replace_time))

咱们能够再次看到,应用.replace() 办法比应用.loc[] 办法快得多。为了更好地直观地理解它有多快,让咱们运行上面的代码:

 print('The differnce: {} %'.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_time
 print("Time using .replace() with dictionary: {} 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_time
 print("Time using multiple .replace(): {} sec".format(list_time))

比拟这两种办法,能够看到应用字典的运行速度快了大概 22%。

应用字典能够替换几个不同列上的雷同值。咱们想把所有种族分成三大类: 黑人、亚洲人和白人。这里的代码也非常简单。应用嵌套字典: 外键是咱们要替换值的列名。值是另一个字典,其中的键是要替换的字典。

 start_time = time.time()
 names.replace({'Ethnicity': {'ASIAN AND PACI': 'ASIAN', 'ASIAN AND PACIFIC ISLANDER': 'ASIAN',
 'BLACK NON HISPANIC': 'BLACK', 'BLACK NON HISP': 'BLACK',
 'WHITE NON HISPANIC': 'WHITE', 'WHITE NON HISP': 'WHITE'}})
 print("Time using .replace() with dictionary: {} sec".format (time.time() - start_time))

总结

  • 应用.iloc[] 函数能够更快地抉择行和列并且它比 loc[] 要快,然而 loc[] 提供了一些更不便的性能,如果速度不是优先思考或者 iloc[] 实现的比拟麻烦的话,再思考应用 loc[]。
  • 应用内置的 replace() 函数比应用传统办法快得多。
  • 应用 python 字典替换多个值比应用列表更快。

本文代码:https://avoid.overfit.cn/post/2c0d17effb934e6da75c33e6402029c6

作者:Youssef Hosni

正文完
 0