一个接一个地循环数据帧(熊猫)
Posted
技术标签:
【中文标题】一个接一个地循环数据帧(熊猫)【英文标题】:Loop through dataframe one by one (pandas) 【发布时间】:2018-01-22 00:57:22 【问题描述】:假设我们有一个包含 A、B 和 C 列的数据框:
df = pd.DataFrame(columns =('A','B','C'), index=range(1))
这些列包含三行数值:
0 A B C
1 2.1 1.8 1.6
2 2.01 1.81 1.58
3 1.9 1.84 1.52
如何遍历从 1 到 3 的每一行,然后执行一个 if 语句,包括添加一些变量:
if B1 > 1.5
calc_temp = A1*10
calc_temp01 = C1*-10
if B2 > 1.5
calc_temp = A2*10
calc_temp01 = C2*-10
if B3 >1.5
calc_temp = A3*10
calc_temp01 = C3*-10
以上甚至可能吗?它必须知道某种范围,即带有某种计数器的全范围数据集编号,是吗? if 语句应引用该特定行。
【问题讨论】:
你可以使用for row in df.iterrows():
由于您要替换calc_temp
和calc_temp01
的已计算值,所以calc_temp
和calc_temp01
的最终值不会依赖于A
和@ 的值987654330@对应最后一次出现的B大于1.5
【参考方案1】:
我觉得你需要iterrows
:
for i, row in df.iterrows():
if row['B'] > 1.5:
calc_temp = row['A'] *10
calc_temp01 = row['C'] *-10
【讨论】:
如果您在循环中访问该行,为什么还要再次调用.loc
?也可以使用for i in range(len(df)):
@cᴏʟᴅsᴘᴇᴇᴅ - 有时过于复杂,谢谢您的支持。
@jezrael - 太棒了,它奏效了。如果我们要在绘图不断更新的同时通过迭代绘制 calc_temp 会怎样。如何实现这一目标?
@Bondeaux - 难题,如果需要绘图。也许最好的方法是使用示例数据、所需的输出和您尝试的内容创建新问题。谢谢。【参考方案2】:
如何高效迭代
如果您确实需要迭代 Pandas 数据框,您可能希望避免使用 iterrows()。有不同的方法,通常的iterrows()
远不是最好的。 itertuples() 可以快 100 倍。
简而言之:
作为一般规则,使用df.itertuples(name=None)
。特别是当您有固定数量的列且少于 255 列时。 见第 (3) 点
否则,请使用df.itertuples()
,除非您的列包含特殊字符,例如空格或“-”。 见第 (2) 点
使用最后一个示例,即使您的数据框有奇怪的列,也可以使用itertuples()
。 见第 (4) 点
如果您无法使用以前的解决方案,请仅使用iterrows()
。 见第 (1) 点
在 Pandas 数据框中迭代行的不同方法:
生成一百万行四列的随机数据框:
df = pd.DataFrame(np.random.randint(0, 100, size=(1000000, 4)), columns=list('ABCD'))
print(df)
1) 常用的iterrows()
很方便,但是太慢了:
start_time = time.clock()
result = 0
for _, row in df.iterrows():
result += max(row['B'], row['C'])
total_elapsed_time = round(time.clock() - start_time, 2)
print("1. Iterrows done in seconds, result = ".format(total_elapsed_time, result))
2) 默认的itertuples()
已经快很多了,但它不适用于My Col-Name is very Strange
等列名(如果您的列重复或列名不能简单地转换为Python 变量名)。:
start_time = time.clock()
result = 0
for row in df.itertuples(index=False):
result += max(row.B, row.C)
total_elapsed_time = round(time.clock() - start_time, 2)
print("2. Named Itertuples done in seconds, result = ".format(total_elapsed_time, result))
3) 使用 name=None 的默认 itertuples()
更快,但不是很方便,因为您必须为每列定义一个变量。
start_time = time.clock()
result = 0
for(_, col1, col2, col3, col4) in df.itertuples(name=None):
result += max(col2, col3)
total_elapsed_time = round(time.clock() - start_time, 2)
print("3. Itertuples done in seconds, result = ".format(total_elapsed_time, result))
4) 最后,命名为itertuples()
比上一点要慢,但您不必为每列定义一个变量,它适用于诸如My Col-Name is very Strange
之类的列名。
start_time = time.clock()
result = 0
for row in df.itertuples(index=False):
result += max(row[df.columns.get_loc('B')], row[df.columns.get_loc('C')])
total_elapsed_time = round(time.clock() - start_time, 2)
print("4. Polyvalent Itertuples working even with special characters in the column name done in seconds, result = ".format(total_elapsed_time, result))
输出:
A B C D
0 41 63 42 23
1 54 9 24 65
2 15 34 10 9
3 39 94 82 97
4 4 88 79 54
... .. .. .. ..
999995 48 27 4 25
999996 16 51 34 28
999997 1 39 61 14
999998 66 51 27 70
999999 51 53 47 99
[1000000 rows x 4 columns]
1. Iterrows done in 104.96 seconds, result = 66151519
2. Named Itertuples done in 1.26 seconds, result = 66151519
3. Itertuples done in 0.94 seconds, result = 66151519
4. Polyvalent Itertuples working even with special characters in the column name done in 2.94 seconds, result = 66151519
This article is a very interesting comparison between iterrows and itertuples
【讨论】:
以上是关于一个接一个地循环数据帧(熊猫)的主要内容,如果未能解决你的问题,请参考以下文章