Как усреднить два значения в одном столбце с pandas итеративным способом? - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь обработать некоторые данные в python, используя pandas для создания фрейма данных, но у меня возникают проблемы с манипулированием данными внутри каждого столбца. По сути, мне нужно для каждого столбца в фрейме данных, который не является [Глубина], проверять каждое значение в столбце, если оно выше 95-го процентиля. Если это так, значение должно быть заменено средним значением одного предыдущего и следующего.

Я хотел использовать функции для выполнения первой части, а затем выполнить итерацию для каждого столбца ... но он на самом деле не работает, и я не уверен, почему.

Код на данный момент

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

'''
Function do remove the "spikes", data points above the 95th percentile
'''

def removespikes (x):
perc = np.percentile(x, 95)
for i in x:
    if i == 0 or x <= perc:
        pass
    else:
        i = mean(i-1, i+1)
    return x

df=pd.read_excel(r"Dati.xlsx")

for column in df:
if column == 'Depth':
    pass #there is no need to do it for the column Depth
else:
    col = df[column]
    col = removespikes(col)

plt.plot(df['Depth'], x, color=colline,
   marker='o', ms=1.0,
   linestyle='-', lw=0.2)
   plt.savefig('{}.png'.format(column))
   plt.clf()

Последняя часть - это часть построения графика, но это не вызывает у меня никаких проблем .. . любой совет? Я знаю, что есть более простой способ сделать это (на этот раз, используя сам excel), но поскольку я пытаюсь выучить python, я пытаюсь заставить себя использовать его ...

Данные Я использую, можно найти в этом Dropbox ссылка

Ответы [ 2 ]

2 голосов
/ 09 июля 2020

Если я правильно понимаю ваш подход, то я заметил следующие основные проблемы в вашем коде:

  • Во-первых, в вашей функции removespikes() x является столбцом values ​​, поэтому сравнение его с perc, которое является единственным значением, не работает. Вместо этого я бы использовал сравнение каждого значения в столбце с perc на каждой итерации.
  • Кроме того, i в вашем l oop - это значение в столбце x. Выполнение mean на i-1 и i+1 не приводит к доступу к предыдущему и следующему элементам в столбце, как вы упомянули, что вы пытаетесь сделать (фактически оно возвращает вам то же значение). Мой подход заключался бы в использовании enumerate для получения индекса каждого значения в столбце, а также самого значения, а затем вызовите mean(x[index-1], x[index+1]), который обращается к предыдущему и следующему элементам в x.
  • При построении графика вы передаете x в plt.plot(), но x - это локальная переменная в removespikes(), поэтому она недоступна вне этой функции. Я предполагаю, что вы хотите построить новые столбцы по отношению к глубине, поэтому я бы переместил построение внутрь l oop, как показано ниже, с параметром col вместо x.

Вот реализованные изменения

def removespikes(x):
    perc = np.percentile(x, 95)
    for index, value in enumerate(x):
        if index == 0 or value <= perc or index == len(x)-1:
            pass
        else:
            value = mean(x[index-1], x[index+1])
            x[index] = value
    return x

for column in df:
    if column == 'Depth':
        pass #there is no need to do it for the column Depth
    else:
        col = df[column]
        col = removespikes(col)
        plt.plot(df['Depth'], col, marker='o', ms=1.0,linestyle='-', lw=0.2)

Приносим извинения, если я вообще неправильно понял ваш вопрос. Надеюсь, это поможет!

0 голосов
/ 09 июля 2020

Я знаю, что в названии написано «итеративно», но вы делаете это в облаке также как ...

import pandas as pd


def removespikes(frame, column: str, limiter: float = 95., inter_limit: int = 1, inplace=False):
    if not inplace:
        frame = frame.copy()
# filter the cloumn and replace all values greater than 95 with NaN
    frame[column][frame[column] > limiter] = pd.np.nan
#interpolte missing data (max. linear interpolation , from both sides, see test frame)
    frame[column].interpolate(limit=inter_limit, limit_direction='both', limit_area='inside', inplace=True)
    if not inplace:
        return frame

# test dataframe
perc = [80, 85, 96, 85, 87, 90, 96, 96, 94, 82, 91, 96, 96, 96, 94]
depth = list(range(len(perc)))

df = pd.DataFrame({'perc': perc, 'Depth': depth})

removespikes(df, 'perc', inplace=True)
#plot all cloumns, exclude "Depth"
df.loc[:, df.columns != 'Depth'].plot(marker='o', ms=1.0, linestyle='-', lw=0.2)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...