【问题标题】:Can a python for loop affect the final dataframe resultpython for循环会影响最终的数据帧结果吗
【发布时间】:2021-01-13 14:27:23
【问题描述】:

我发现这两个伪代码脚本会产生不同的结果。

脚本 1:

# Load dataframe
Df_1 = read_csv(path to file.csv)
# Start iteration through list of dates
For date in range(250):
    Df_1 = Function_that_calculates_stuff(Df_1)
    # Grab data I’m interested in and save to text file
    row = pd.DataFrame([[str(Df_1.iloc[1,1]), ]])
    Txt_file = Txt_file.append(row, ignore_index = True)

# After loop, save dataframes
Df_1.to_csv(path to file.csv)

脚本 2:

For number in range(250):
   For date in range(1):
     # Load dataframe
     Df_1 = read_csv(path to file.csv)
     Df_1 = Function_that_calculates_stuff(Df_1)
     # Grab data I’m interested in and save to text file
     row = pd.DataFrame([[str(Df_1.iloc[1,1]), ]])
     Txt_file = Txt_file.append(row, ignore_index = True)
     Df_1.to_csv(path to file.csv)

我很困惑为什么会这样。我曾尝试一次一行地浏览代码,但找不到任何可以解释这一点的东西。

嵌套循环可以改变加载或保存在其中的数据吗?

有没有办法创建一种大坝来防止不需要的数据“泄漏”到循环的开头。

【问题讨论】:

  • 这些操作方式不同,在第一个示例中,您打开文件一次并加载数据。然后,您将遍历将结果重新分配给 DF_1 的行,基本上就像过滤样式一样。所以在循环的每一次迭代中,都会根据上一次循环作用于DF_1中的数据。但是,在第二个示例中,您始终使用从文件加载的数据的新副本开始每个循环,而不是从上一个循环中剩余的数据。所以这些可能会非常不同。

标签: python-3.x for-loop nested-loops


【解决方案1】:

您提供的两个代码片段不做同样的事情。本质上,在第一个代码 sn-p 中,您从文件中读取了一次数据。我们将其称为初始状态。然后,对于循环的每次迭代,您调用函数将数据传递给它,然后将结果存储回同一个变量,从而覆盖数据。

因此,当下一次迭代开始时,您将使用循环最后一次迭代的数据,而不是从文件加载的初始数据。这将像过滤或减少过程一样继续。每次迭代都可能减少或丰富上一次循环的数据。

在您的第二个代码中,您总是从文件中加载数据。因此,循环的每次迭代都应用于原始数据,而不是作用于前一个循环中的前一个数据上的数据。

由于您在示例中没有给出太多来重现问题,因此我构建了一个简单的示例来演示这一点

def divides_by_i(num_data, i):
    return [num for num in num_data if num % i == 0]


data = ("0,1,2,3,4,5,6,7,8,9,"
        "10,11,12,13,14,15,16,17,18,19,20,"
        "20,21,22,23,24,25,26,27,28,29,30")

nums_data = [int(num) for num in data.split(",")]

for i in range(1, 4):
    nums_data = divides_by_i(nums_data, i)
with open("out1.txt", "w") as out1:
    out1.write(",".join(str(num) for num in nums_data))

for i in range(1, 4):
    for _ in range(1):
        nums_data = [int(num) for num in data.split(",")]
        nums_data = divides_by_i(nums_data, i)
        with open("out2.txt", "w") as out1:
            out1.write(",".join(str(num) for num in nums_data))

输出

First loop: 0,6,12,18,24,30
Second loop: 0,3,6,9,12,15,18,21,24,27,30

在第一个循环中,它获取所有数据并用可整除该循环迭代次数的数据覆盖它。下一次迭代将只作用于上一次迭代的数字。我们将最后的数据写入文件。

在第二个循环中,它总是从原始数字中读取数据并应用结果,然后将此迭代的结果保存在任何其他输出上。因此,基本上在第二个循环中,该函数将作用于原始数据并应用该函数并每次保存输出,这意味着您会丢失前一个循环的任何输出。

所以问题不在于您有一个嵌套循环这一事实,而在于您在第一个示例中仅打开一次文件并在第二个示例中的每次迭代中打开它。如果你将那个开口移回循环之外,它的作用是一样的。

【讨论】:

  • 您好,感谢您花时间为我澄清这一点。在我的第二个示例中,我在迭代 0 中加载数据帧。我们将其称为 DF(0),将其放入函数然后保存。然后当循环重新开始时,它会再次加载数据帧,尽管它包含来自 DF(0) 的数据。现在它通过函数,得到 DF(1)。它再次保存并重新开始。这与示例 1 有何不同?
  • 在每次迭代的第二个循环中,您从文件 Df_1 = read_csv(path to file.csv) 加载 DF_1,然后使用函数结果 Df_1 = Function_that_calculates_stuff(Df_1) 更新 Df_1 的值所以到迭代结束时,Df_1 是现在是函数结果的值,而不是文件中的数据。但是在下一次迭代中,您再次加载将 Df_1 放回原始数据的文件并丢失您在上一次迭代中放入的数据
  • 我在示例 2 中以Df_1.to_csv(path to file.csv) 结束每次迭代,并通过使用Df_1 = read_csv(path to file.csv) 再次加载它来重新开始循环。因此,如果我理解正确,我就不会“丢失”数据。
  • 对不起,我现在明白你的意思了
  • 是的,在这种情况下它应该可以工作,你看到什么样的不同
猜你喜欢
  • 1970-01-01
  • 2017-06-27
  • 2020-06-09
  • 1970-01-01
  • 2016-11-11
  • 2020-08-05
  • 2012-06-14
  • 1970-01-01
  • 2021-02-18
相关资源
最近更新 更多