首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Pandas中高效的“For循环”

循环是我们编程技能中的一项固有技能。当我们熟悉任何编程语言时,循环就会成为一个基本的、易于解释的概念。

在这篇博文中,我们将探索遍历pandas dataframe的各种方法,检查每个循环方法的相关运行时。为了验证循环的有效性,我们将生成百万级别的数据,这也是我们在日常处理中经常遇到的数量级。

实验数据集

我们将生成一个包含600万行和4列的DataFrame。每一列将被分配一个0到50之间的随机整数。

Iterrows

我们通过基于以下标准引入一个新的列' e '来扩展数据框架' df ':

如果' a '等于0,那么' e '取' d '的值。如果' a '在0(不包括)到25(包括)的范围内,' e '计算为' b '减去' c '。如果以上条件都不成立,则计算“e”为“b”+“c”。

首先我们使用pandas提供的' iterrows() '函数遍历DataFrame ' df '。' iterrows() '函数遍历DataFrame的行,在迭代期间返回(index, row)对。

import time

start = time.time()

# Iterating through DataFrame using iterrows

for idx, row in df.iterrows():

  if row.a == 0:

      df.at[idx,'e'] = row.d

  elif (row.a <= 25) & (row.a > 0):

      df.at[idx,'e'] = (row.b)-(row.c)

  else:

      df.at[idx,'e'] = row.b + row.c

end = time.time()

print(end - start)

# time taken: 335.212792634964

iterrows()函数需要335秒(约5.5分钟)来实现对600万行的操作。

Itertuples

另一种遍历pandas DataFrame的方法是使用' itertuples ',它以命名元组的形式遍历DataFrame行。

下面代码说明了如何使用' itertuples '访问元素。生成的行对象将索引作为第一个字段,然后是数据框的列。

for row in df[:1].itertuples():

  print(row) ## accessing the complete row - index following by columns

  print(row.Index) ## accessing the index of the row

  print(row.a) ## accessing the value of column 'a'

使用下面的代码,使用itertuples()遍历DataFrame df。

start = time.time()

# Iterating through namedtuples

for row in df.itertuples():

  if row.a == 0:

      df.at[row.Index,'e'] = row.d

  elif (row.a <= 25) & (row.a > 0):

      df.at[row.Index,'e'] = (row.b)-(row.c)

  else:

      df.at[row.Index,'e'] = row.b + row.c

end = time.time()

print(end - start)

## Time taken: 41 seconds

在DataFrame上执行所需的操作,itertuples()函数耗时约54秒,比iterrows()函数快6倍。

字典

迭代DataFrame行的另一种方法是将DataFrame转换为字典,这是一种轻量级的内置数据类型。我们遍历该字典以执行所需的操作,然后将更新后的字典转换回DataFrame。转换可以使用' to_dict() '函数来实现。

start = time.time()

# converting the DataFrame to a dictionary

df_dict = df.to_dict('records')

# Iterating through the dictionary

for row in df_dict[:]:

  if row['a'] == 0:

      row['e'] = row['d']

  elif row['a'] <= 25 & row['a'] > 0:

      row['e'] = row['b']-row['c']

  else:

      row['e'] = row['b'] + row['c']

# converting back to DataFrame

df4 = pd.DataFrame(df_dict)

end = time.time()

print(end - start)

## Time taken: 31 seconds

字典方法大约需要31秒,大约比' itertuples() '函数快11倍。

数组列表

我们还可以将DataFrame转换为一个数组,遍历该数组以对每行(存储在列表中)执行操作,然后将该列表转换回DataFrame。

start = time.time()

# create an empty dictionary

list2 = []

# intialize column having 0s.

df['e'] = 0

# iterate through a NumPy array

for row in df.values:

  if row[0] == 0:

      row[4] = row[3]

  elif row[0] <= 25 & row[0] > 0:

      row[4] = row[1]-row[2]

  else:

      row[4] = row[1] + row[2]

## append values to a list

  list2.append(row)

## convert the list to a dataframe

df2 = pd.DataFrame(list2, columns=['a', 'b', 'c', 'd','e'])

end = time.time()

print(end - start)

#Time Taken: 21 seconds

花费的时间约为21秒(比iterrows快16倍),这与遍历字典所花费的时间非常接近。

字典和数组是内置的轻量级数据结构,因此迭代DataFrame所需的时间最少。

总结

在文探索了使用循环遍历DataFrame的四种不同方法。

' iterrows '函数在遍历DataFrame时显示出最高的时间消耗。与“iterrows”函数相比,使用“itertuples”函数可以使DataFrame迭代的速度提高6倍。在字典和数组上迭代被证明是最有效的方法,使用循环提供最快的迭代时间和最佳的数据操作。

当然,在处理大型数据集时,最佳实践是矢量化。向量化上述代码将执行时间减少到0.29秒(比遍历数组快72倍)。但是使用矢量化时会增加开发的成本,所以在一些时候为了我们开发方便,可以选择一个比较快速for循环来替代矢量化。当然,如果你对矢量化非常的了解,那还是推荐继续使用。

作者:Anmol Tomar

MORE

kaggle比赛交流和组队

喜欢就关注一下吧:

点个在看你最好看!

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OTY_Nvld2hIEDjOSqtFn3wXA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券