一个接一个地循环数据帧(熊猫)

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_tempcalc_temp01 的已计算值,所以calc_tempcalc_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

【讨论】:

以上是关于一个接一个地循环数据帧(熊猫)的主要内容,如果未能解决你的问题,请参考以下文章

在熊猫中连接/附加许多数据帧

将值从一个数据帧切片复制到另一个:使用“IndexSlice”的多索引熊猫数据帧的切片是不是总是一致地排序?

循环遍历层后附加熊猫数据帧

while循环加入熊猫数据帧

使用熊猫在python中循环多个excel文件

熊猫矢量化而不是两个数据帧的循环