【问题标题】:For loops to iterate through columns of a csvFor 循环遍历 csv 的列
【发布时间】:2021-03-04 21:40:01
【问题描述】:

我对 python 和一般编程非常陌生(这是我的第一门编程语言,大约一个月前开始使用)。

我有一个 CSV 文件,其中的数据排序如下(CSV 文件数据在底部)。有 31 列数据。第一列(波长)必须作为自变量(x)读入,对于第一次迭代,它必须在第二列(即标记为“观察”的第一列)中作为因变量(y)读入。然后,我尝试将高斯+线模型拟合到数据中,并从数据中提取高斯 (mu) 的平均值,该数据应存储在数组中以供进一步分析。应针对每组观察重复此过程,而读取的 x 值必须保持不变(即来自 Wavelength 列)

这是我目前如何读取数据的代码:

import numpy as np #importing necessary packages
import matplotlib.pyplot as plt
import pandas as pd
import scipy as sp
from scipy.optimize import curve_fit
e=np.exp
spectral_data=np.loadtxt(r'C:/Users/Sidharth/Documents/Computing Labs/Project 1/Halpha_spectral_data.csv', delimiter=',', skiprows=2) #importing data file
print(spectral_data)
x=spectral_data[:,0] #selecting column 0 to be x-axis data
y=spectral_data[:,1] #selecting column 1 to be y-axis data

所以我需要将该过程自动化,这样就不必手动将 y=spectral_data[:,1] 更改为 y=spectral_data[:,2] 直到 y=spectral_data[:,30]迭代,它可以简单地自动化。

我生成高斯拟合的代码如下:

plt.scatter(x,y) #produce scatter plot
plt.title('Observation 1')
plt.ylabel('Intensity (arbitrary units)')
plt.xlabel('Wavelength (m)')
plt.plot(x,y,'*')
plt.plot(x,c+m*x,'-') #plots the fit

print('The slope and intercept of the regression is,', m,c)
m_best=m
c_best=c
def fit_gauss(x,a,mu,sig,m,c):
    gaus = a*sp.exp(-(x-mu)**2/(2*sig**2))
    line = m*x+c
    return gaus + line

initial_guess=[160,7.1*10**-7,0.2*10**-7,m_best,c_best]
po,po_cov=sp.optimize.curve_fit(fit_gauss,x,y,initial_guess)

高斯似乎很合适(如图所示),所以这个高斯的平均值(即峰值的 x 坐标)是我必须从中提取的值。均值的值在控制台中给出(用 mu 表示):

The slope and intercept of the regression is, -731442221.6844947 616.0099144830941
The signal parameters are
 Gaussian amplitude = 19.7 +/- 0.8
 mu = 7.1e-07 +/- 2.1e-10
 Gaussian width (sigma) = -0.0 +/- 0.0
and the background estimate is
 m = 132654859.04 +/- 6439349.49
 c = 40 +/- 5

所以我的问题是,如何迭代从 csv 读取数据的过程,这样我就不必手动更改从 y 获取数据的列,然后 如何存储读取的每次迭代中的 mu 值,以便以后可以对该平均值进行进一步的分析/计算?

我的想法是我应该使用 for-loop,但我不知道该怎么做。

图中显示的橙色线是我之前尝试过的一些代码的结果。我认为这无关紧要,这就是为什么它不在问题的主要部分,但如果有必要,这就是全部。

x=spectral_data[:,0] #selecting column 0 to be x-axis data
y=spectral_data[:,1] #selecting column 1 to be y-axis data
plt.scatter(x,y) #produce scatter plot
plt.title('Observation 1')
plt.ylabel('Intensity (arbitrary units)')
plt.xlabel('Wavelength (m)')
plt.plot(x,y,'*')
plt.plot(x,c+m*x,'-') #plots the fit

【问题讨论】:

    标签: python numpy for-loop matplotlib scipy


    【解决方案1】:

    通常当您遇到这样的问题时,尝试将其分解为必须保持不变的内容(在您的示例中,x 数据和分析代码),以及必须更改的内容(y 数据,或更具体的索引告诉代码的其余部分什么是 y 数据的正确列),以及如何保留您希望进一步存储的值。
    一旦你弄清楚了这一点,我们需要形式化正确的循环以及如何存储我们想要的值。对于后者,一种简单的方法是将它们存储在一个列表中,因此我们将启动一个空列表,并在每次循环迭代结束时将值附加到该列表中。

    mu_list = [] # will store our mu's in this list
    for i in range(1, 31): # each iteration i gets a different value, starting with 1 and ends with 30 (and not 31)
        x = spectral_data[:, 0]
        y = spectral_data[:, i]
        # Your analysis and plot code here #
        mu = po[1] # Not sure po[1] is the right place where your mu is, please change it appropriately...
        mu_list.append(mu) # store mu at the end of our growing mu_list
    

    您将在mu_list 下获得一个包含 30 个mu 的列表。

    现在,请注意我们不必在循环内执行所有操作,例如 x 与 i 无关(仅加载 x 一次 - 提高性能)并且分析代码基本相同,除了 a不同的输入(y 数据),所以我们可以为它定义一个函数(使更大的代码更具可读性的好习惯),所以很可能我们可以将它们从循环中取出。我们可以在循环前写x = spectral_data[:, 0],定义一个分析数据并返回mu的函数:

    def analyze(x, y):
        # Your analysis and plot code here #
        mu = po[1]
        return mu
    
    x = spectral_data[:, 0]
    mu_list = [] # will store our mu's in this list
    for i in range(1, 31):
        y = spectral_data[:, i]
        mu_list.append(analyze(x,y)) # Will calculate mu using our function, and store it at the end of our growing mu_list
    

    【讨论】:

    • 谢谢,这真的很有帮助。我想我也理解你是如何使用 for 循环的,这很棒。实际上,存储的 mu 值应该用于以后计算每列数据的速度 (v)。因此,我认为如果我在 for 循环中为每列数据包含从 mu 计算 v 并将 v 的值存储在列表中,效率会更高。然后我可以在最后(在 for 循环之外)打印 v 的值。如果我错了,请纠正我,否则,对您的回答非常满意。
    • [1/2] 不客气。当然,您的问题的答案是肯定的和否定的。由于它是一个小项目,无论是代码复杂度还是数据量,在循环内计算 v 并仅存储 v 是非常有意义的。
    • [2/2] 但是对于一般情况下,您希望有效地运行程序(就执行时间和计算资源而言),您可能希望循环内的操作尽可能少可能的。原因是通常每次计算一个元素比将所有元素都计算为向量要慢。技术术语是矢量化。 Numpy 等库内置了支持向量计算的函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多