【问题标题】:append dataframe in nested loop在嵌套循环中附加数据框
【发布时间】:2021-02-05 08:03:49
【问题描述】:

我有以下代码根据 2 个变量(bh 和频率)在函数中进行一些计算。当我以固定值 bh 运行没有循环的代码时,我得到了一个正确的输出和保存在 .csv 文件中的数据框。:

    bh   frequency                Re                  Im
0  1e-05         1  5.86848609615851  -0.999374346845734
1  1e-05        11  4.34298196390882  -0.994875549720418
2  1e-05        21  3.93236459069042   -0.99112086235206
3  1e-05        31  3.68545733552675  -0.987695572513367
4  1e-05        41  3.50849758486341  -0.984487932588323

但是,当我在 bh 上的循环中编码时,我想在 bh 值和频率列表上循环,我得到与以前相同的输出,这意味着它不会循环。是否有人有解决方案来修改数据框或将 eaxh bh 循环输出保存在新的 .csv 中,以便稍后绘制数据。

from mpmath import *
import numpy as np
import cmath
import math
import pandas as pd

mp.dps = 15; mp.pretty = True
a = mpf(0.25)
b = mpf(0.25)
z = mpf(0.75)
frequency = np.arange(1, 50, 10)  # frequency range
bh = np.arange(10e-6, 30e-6, 10e-6) #10e-6 # width
print(bh)
D = 1e-6 #7.8e-4  # diffusivity
gamma = 0.5772 # Euler constant
v = []
w =[]
i = []
def q(frequency):
  for i in bh:
    # for f in frequency:
      omega = (((i ** 2) * 2 * math.pi * frequency) / D)  # depends on bh and frequency
      u = ((-j/(math.pi * omega))*meijerg([[1, 3/2], []], [[1, 1], [0.5, 0]], j*omega))
      v = np.real(u)
      w = np.imag(u)
      return i, frequency, v, w
#transpose arrays
T = np.vectorize(q)
print(T(frequency))
df = np.array(T(frequency)).T
print(df)
# create DataFrame
df1 = pd.DataFrame(data=df, columns=['bh', 'frequency','Re', 'Im'])
print(df1)
#save in .csv
df1.to_csv('C:\\Users\\calculations\\T.csv')

【问题讨论】:

    标签: python pandas dataframe nested-loops


    【解决方案1】:

    我不完全确定我是否理解您的问题域,但您似乎正在返回循环的第一次迭代。通过在循环中使用 return,您基本上可以提前终止 for 循环。这应该在循环之外。此外,您不会将值保存在数组 v、w 和 i 中。您正在覆盖变量。

    我做了一些修改(根据您的问题域可能不正确),但它应该可以完成您想要完成的工作。

    from mpmath import *
    import numpy as np
    import cmath
    import math
    import pandas as pd
    
    mp.dps = 15; mp.pretty = True
    a = mpf(0.25)
    b = mpf(0.25)
    z = mpf(0.75)
    frequencies = np.arange(1, 50, 10)  # frequency range
    bh = np.arange(10e-6, 30e-6, 10e-6) #10e-6 # width
    print(bh)
    D = 1e-6 #7.8e-4  # diffusivity
    gamma = 0.5772 # Euler constant
    v = []
    w = []
    i = []
    bhs = []
    freqs = []
    def q(frequencies):
      for frequency in frequencies:
        for i in bh:
          # for f in frequency:
            omega = (((i ** 2) * 2 * math.pi * frequency) / D)  # depends on bh and frequency
            u = ((-j/(math.pi * omega))*meijerg([[1, 3/2], []], [[1, 1], [0.5, 0]], j*omega))
            v.append(np.real(u))
            w.append(np.imag(u))
            bhs.append(i)
            freqs.append(frequency)
      return bhs, freqs, v, w
    
    data = np.array(q(frequencies)).T
    # create DataFrame
    df1 = pd.DataFrame(data=data, columns=['bh', 'frequency','Re', 'Im'])
    df1
    

    输出:

        bh  frequency             Re                 Im
    0   1e-05   1   5.86848609615851    -0.999374346845734
    1   2e-05   1   4.98625732244539    -0.99786698700645
    2   1e-05   11  4.34298196390882    -0.994875549720418
    3   2e-05   11  3.46384911041305    -0.983559190454865
    4   1e-05   21  3.93236459069042    -0.99112086235206
    5   2e-05   21  3.05626898509369    -0.972212391507732
    6   1e-05   31  3.68545733552675    -0.987695572513367
    7   2e-05   31  2.81234917403506    -0.962167989599812
    8   1e-05   41  3.50849758486341    -0.984487932588323
    9   2e-05   41  2.63833200578647    -0.952979213441469
    10  1e-05   1   5.86848609615851    -0.999374346845734
    11  2e-05   1   4.98625732244539    -0.99786698700645
    12  1e-05   11  4.34298196390882    -0.994875549720418
    13  2e-05   11  3.46384911041305    -0.983559190454865
    14  1e-05   21  3.93236459069042    -0.99112086235206
    15  2e-05   21  3.05626898509369    -0.972212391507732
    16  1e-05   31  3.68545733552675    -0.987695572513367
    17  2e-05   31  2.81234917403506    -0.962167989599812
    18  1e-05   41  3.50849758486341    -0.984487932588323
    19  2e-05   41  2.63833200578647    -0.952979213441469
    20  1e-05   1   5.86848609615851    -0.999374346845734
    21  2e-05   1   4.98625732244539    -0.99786698700645
    22  1e-05   11  4.34298196390882    -0.994875549720418
    23  2e-05   11  3.46384911041305    -0.983559190454865
    24  1e-05   21  3.93236459069042    -0.99112086235206
    25  2e-05   21  3.05626898509369    -0.972212391507732
    26  1e-05   31  3.68545733552675    -0.987695572513367
    27  2e-05   31  2.81234917403506    -0.962167989599812
    28  1e-05   41  3.50849758486341    -0.984487932588323
    29  2e-05   41  2.63833200578647    -0.952979213441469
    

    【讨论】:

    • 感谢 Oddaspa,它工作正常,我只是颠倒了频率和 bh 循环,所以我对每个 bh 的频率进行了全面扫描。有什么方法可以对新列或文件进行每次扫描?
    • 取决于你想要什么?要将每次扫描保存在文件中,请使用 df1.to_csv("name_of_file.csv")。要将所有扫描添加到单个,您可以使用 pandas 的 df1.join(df2) 函数。
    【解决方案2】:

    我建议 (1) 提前生成 bhfrequency 的笛卡尔积,以及 (2) 仅矢量化您真正需要的部分,因为已知 np.vectorization 成本高昂(即 meijerg()不是矢量化函数)。笛卡尔积可以由pd.MultiIndex.from_product 完成(见this answer)。

    # run your code until gamma = 0.5772
    
    # Cartesian product of input variables
    idx = pd.MultiIndex.from_product([bh, frequency], names=["bh", "frequency"])
    df = pd.DataFrame(index=idx).reset_index()
    
    # Omega is vectorized naturally.
    omega = (df["bh"].values**2 * df["frequency"].values) * (2 * math.pi / D)
    
    # vectorize meijerg() only, so other operations won't interrupt with this
    def f_u(omega_elem):
        return (-j/(math.pi * omega_elem)) * meijerg([[1, 3/2], []], [[1, 1], [0.5, 0]], j*omega_elem)
    
    f_u_vec = np.vectorize(f_u, otypes=[np.complex128]) # output complex
    
    u = f_u_vec(omega)  # np.complex128
    df["Re"] = np.real(u)
    df["Im"] = np.imag(u)
    
    # output (please make sure your arange was set correctly)
    df
    Out[35]: 
            bh  frequency        Re        Im
    0  0.00001          1  5.868486 -0.999374
    1  0.00001         11  4.342982 -0.994876
    2  0.00001         21  3.932365 -0.991121
    3  0.00001         31  3.685457 -0.987696
    4  0.00001         41  3.508498 -0.984488
    5  0.00002          1  4.986257 -0.997867
    6  0.00002         11  3.463849 -0.983559
    7  0.00002         21  3.056269 -0.972212
    8  0.00002         31  2.812349 -0.962168
    9  0.00002         41  2.638332 -0.952979
    

    如果你想保存单独的 csv 文件,你可以这样做:

    for bh_elem in bh:
        fname = f"bh={bh_elem:.4e}.csv"
        df_save = df[(df["bh"]==bh_elem)]
        df_save.to_csv(fname)
    

    注意在 pandas 1.1.3 和 python 3.7、debian 10 64 位上测试

    【讨论】:

    • 亲爱的比尔,非常感谢,我收到一个错误:u = f_u_vec(arr_omega) NameError: name 'arr_omega' is not defined?关于保存在各种.csv中的最后几行我应该在结束了吧?
    • 对不起,我的错。它应该只是omega。是的,只需在 df 生成后保存
    • 亲爱的比尔,在 f_u 方法中,我想添加一些复杂的计算,将 omega_elem 作为变量,因此需要对输出进行矢量化。我知道我可以从 f_u 多次返回,但我不确定后续的向量化。例如我想添加: asympt = (4 / (math.pi)) * (-(1 / 2) * np.log(omega_elem) + 3 / 2 - gamma - j * ((math.pi) / 4) ) 所以我像以前一样返回除了 u 之外的 asymt 但是我不能翻译矢量化。
    • 请发布另一个问题,因为提出的新问题的性质与原始帖子不同;)
    • 顺便说一句,SO 不是一个讨论论坛,所以我们不应该像这样在 cmets 中进行讨论。我希望系统或版主尽快清理所有这些 cmets。
    猜你喜欢
    • 2021-10-03
    • 2016-09-29
    • 2021-01-13
    • 2019-08-07
    • 2022-07-14
    • 2023-01-11
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    相关资源
    最近更新 更多