How to calculate stdev inside a For Loop with conditions in Python

Viewed 76

I have a CSV file, structured in two columns: "Time.s", "Volt.mv". Example: 0, 1.06 0.0039115, 1.018 0.0078229, 0.90804

So, I have to return time values ​​that exceed the threshold of 0.95 indicating the deviation of each value with respect to the average of that time interval.

I calculated the average like this:

ecg_time_mean = ecg["Time.s"].mean()
print(ecg_time_mean)

Then, I tried to make a For Loop with condition:

ecg_dev = []

for elem in ecg["Time.s"]:
    if elem > 0.95:
        deviation = ecg["Time.s"].std()
        sqrt = deviation**(1/2.0)
        dev = sqrt/ecg_time_mean
        ecg_dev.append(elem)

ecg["Deviation"] = dev
print(ecg)

And I would like to print the output in a new column called "Deviation". This is the output: no If Condition taken into consideration and column Deviation with the same number in each row.

I can't understand the problem. Thank you in advance, guys!

2 Answers
  1. You are adding "elem" and not your dev into the new column.
  2. You didnt assign ecg_dev to your new column; you assigned a VALUE dev to that column.
  3. If you notice, dev is actually the same value throughout your loop. The only variables factored into the calculation of dev is std and mean, which encompass the entire data, thus negating any looping.
  4. And ecg_dev is different length as your ecg because it is shorter than your ecg (due to the if). So even if you assign it to the new column, it will fail.
  5. The sqrt is fixed across ecg, you do not need to recalculate it inside the loop.

I do not understand what you want based on what you wrote here:

So, I have to return time values ​​that exceed the threshold of 0.95 indicating the deviation of each value with respect to the average of that time interval.

  • What is Time.s? Is it a monotonically-increasing time or is it an interval length? If it is monotonically-increasing time, "deviation of each value with respect to the average" do not make sense. If it is an interval, then "average of that time interval" do not make sense.
  • For Time.s > 0.95, you want the deviation of what value (or column) with respect to the average of what column during the time interval.

I will amend my answer when you clarify these to find in the placeholder function. (Question was clarified in the comments)

It looks like you want the deviation of time taken from the mean time taken for the cases where volt.mv exceeds 0.95. In this case you do not need std() at all.

ecg_time_mean = ecg["Time.s"].mean()
ecg['TimeDeviationFromMean'] = ecg['Time.s'] - ecg_time_mean
ecg_above95 = ecg[ecg['Volt.mv'] > 0.95]

The ecg_above95 dataframe should be what you need.

The issue is that you are setting each of the values to the last calculation of dev.

To do what you want with the for loop, you have to make two edits:

First, append the calculated dev to ecg_dev

ecg_dev.append(dev) #not elem

Side step, you need to append nans when elem <= 0.95

if elem > 0.95:
    ....
else: ecg_dev.append(np.nan)

Second, you need to set the column to ecg_dev

ecg['Deviation'] = ecg_dev

Assuming that you are using a Pandas DataFrame, however, you can speed up your code by skipping the for loops altogether and calculate directly.

ecg['Deviation'] = #deviation calculation
ecg['Deviation'][ecg['Time.s'] <= 0.95] = np.nan
Related