Вставка отсутствующих чисел в фрейм данных

У меня есть программа, которая идеально измеряет температуру каждую секунду. Однако на самом деле этого не происходит. Иногда он пропускает секунду или выходит из строя на 400 секунд, а затем решает начать запись снова. Это оставляет пробелы в моем фрейме данных 2 на n, где в идеале n = 86400 (количество секунд в день). Я хочу применить к нему какое-то скользящее / скользящее среднее, чтобы получить более красивый график, но если я сделаю это с «сырыми» файлами данных, количество точек данных станет меньше. Это показано здесь, посмотрите на ось x. Я знаю, что «хорошие данные» пока не выглядят хорошо; Я просто играю с некоторыми ценностями.

Итак, я хочу реализовать метод очистки данных, который добавляет данные в фрейм данных. Я думал об этом, но не знаю, как это реализовать. Я думал об этом так:

Если индекс не равен времени, нам нужно добавить число в time = index. Если этот пробел составляет только 1 значение, то мне подойдет среднее значение предыдущего числа и следующего числа. Но если он больше, скажем, не хватает 100 секунд, тогда необходимо создать линейную функцию, которая будет постоянно увеличивать или уменьшать значение.

Итак, я предполагаю, что обучающий набор может быть таким:

index   time   temp 
0       0      20.10
1       1      20.20
2       2      20.20
3       4      20.10
4       100    22.30

Здесь я хотел бы получить значение для индекса 3, времени 3 и значений, отсутствующих между time = 4 и time = 100. Прошу прощения за мои навыки форматирования, я надеюсь, что это понятно.

Как мне это запрограммировать?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
362
2

Ответы 2

Используйте слияние с полным столбцом времени, а затем interpolate:

# Create your table
time = np.array([e for e in np.arange(20) if np.random.uniform() > 0.6])
temp = np.random.uniform(20, 25, size=len(time))
temps = pd.DataFrame([time, temp]).T
temps.columns = ['time', 'temperature']

>>> temps

   time  temperature
0   4.0    21.662352
1  10.0    20.904659
2  15.0    20.345858
3  18.0    24.787389
4  19.0    20.719487

Выше приведена случайная таблица, созданная с отсутствующими данными о времени.

# modify it
filled = pd.Series(np.arange(temps.iloc[0,0], temps.iloc[-1, 0]+1))
filled = filled.to_frame()
filled.columns = ['time'] # Create a fully filled time column
merged = pd.merge(filled, temps, on='time', how='left') # merge it with original, time without temperature will be null
merged.temperature = merged.temperature.interpolate() # fill nulls linearly.

# Alternatively, use reindex, this does the same thing.
final = temps.set_index('time').reindex(np.arange(temps.time.min(),temps.time.max()+1)).reset_index()
final.temperature = final.temperature.interpolate()

>>> merged # or final

    time  temperature
0    4.0    21.662352
1    5.0    21.536070
2    6.0    21.409788
3    7.0    21.283505
4    8.0    21.157223
5    9.0    21.030941
6   10.0    20.904659
7   11.0    20.792898
8   12.0    20.681138
9   13.0    20.569378
10  14.0    20.457618
11  15.0    20.345858
12  16.0    21.826368
13  17.0    23.306879
14  18.0    24.787389
15  19.0    20.719487

Сначала вы можете установить вторые значения как фактические значения времени как таковые:

df.index = pd.to_datetime(df['time'], unit='s')

После этого вы можете использовать встроенные операции временных рядов pandas для повторной выборки и заполнения недостающих значений:

df = df.resample('s').interpolate('time')

При желании, если вы все еще хотите немного сгладить, вы можете использовать для этого следующую операцию:

df.rolling(5, center=True, win_type='hann').mean()

Что будет сглажено с помощью Окно Ханнинга шириной в 5 элементов. Примечание: любое оконное сглаживание будет стоить вам очков по краям.

Теперь ваш фрейм данных будет иметь дату и время (включая дату) в качестве индекса. Это необходимо для метода повторной выборки. Если вы хотите потерять дату, вы можете просто использовать:

df.index = df.index.time

Другие вопросы по теме