Регулярные выражения для сопоставления шаблонов в массивах NumPy и PyTorch
Изучите нативные методы для сопоставления шаблонов, подобных регулярным выражениям, в массивах NumPy и PyTorch без преобразования в строки. Узнайте эффективные методы обнаружения числовых последовательностей с практическими примерами и советами по оптимизации производительности.
Как реализовать сопоставление шаблонов, похожее на регулярные выражения, для числовых последовательностей в массивах numpy или torch?
Существуют ли встроенные методы в чистом numpy или PyTorch для поиска конкретных последовательностей числовых значений, соответствующих определенным логическим шаблонам, аналогично регулярным выражениям, внутри массивов или строк матриц?
Я знаю, что могу преобразовать массив в строки и использовать традиционные регулярные выражения, но я ищу прямой подход, который работает с числовыми данными без преобразования. Какие существуют эффективные методы для сопоставления шаблонов в массивах numpy или тензорах PyTorch?
Сопоставление с образцом числовых последовательностей в стиле регулярных выражений в массивах NumPy и PyTorch
Сопоставление с образцом числовых последовательностей в стиле регулярных выражений в массивах NumPy и PyTorch можно реализовать с помощью нескольких встроенных подходов, которые не требуют преобразования числовых данных в строки. Хотя традиционные регулярные выражения работают с текстом, обе библиотеки предоставляют специализированные функции для сопоставления с образцом в числовых массивах.
Содержание
- Подходы к сопоставлению с образцом в NumPy
- Сопоставление с образцом тензоров PyTorch
- Продвинутые техники сопоставления с образцом
- Рекомендации по производительности
- Практические примеры
Подходы к сопоставлению с образцом в NumPy
Использование векторизованных функций регулярных выражений
В NumPy нет встроенных функций регулярных выражений для числовых массивов, но можно векторизовать модуль регулярных выражений Python для сопоставления с образцом числовых последовательностей при их преобразовании в строки. Однако это все равно включает преобразование в строки:
import numpy as np
import re
# Создание числового массива
data = np.array([101, 124, 979, 430, 1073, 146, 111, 650])
pattern = re.compile(r'1[0-9]{2}') # Сопоставление чисел, начинающихся с 1, за которыми следуют 2 цифры
# Векторизованный подход с преобразованием в строки
vmatch = np.vectorize(lambda x: bool(pattern.match(str(x))))
matches = vmatch(data)
Использование fromregex NumPy для данных из файлов
Для числовых шаблонов, хранящихся в файлах, NumPy предоставляет функцию fromregex, которая может извлекать шаблоны непосредственно из текстовых файлов:
import numpy as np
from io import StringIO
# Текстовые данные с числовыми последовательностями
text = StringIO("101 124 979 430\n146 111 650 983")
pattern = r'(\d+)\s+(\d+)' # Сопоставление двух цифр, за которыми следует пробел и еще цифры
# Создание структурированного массива из совпадений регулярных выражений
result = np.fromregex(text, pattern, [('first', 'i4'), ('second', 'i4')])
Использование математических операций для обнаружения шаблонов
Для чисто числового сопоставления с образцом без преобразования в строки можно использовать математические операции:
import numpy as np
# Поиск последовательностей, где значения увеличиваются на 10
def find_increasing_sequence(arr, step=10):
diffs = np.diff(arr)
return np.where(diffs == step)[0]
data = np.array([5, 15, 25, 30, 40, 50])
indices = find_increasing_sequence(data, step=10) # Возвращает [0, 1, 4]
Сопоставление с образцом тензоров PyTorch
Использование функции torch.match
PyTorch предоставляет встроенную функцию torch.match для сопоставления с образцом в тензорах:
import torch
# Шаблонные и образцовые тензоры
template = torch.tensor([101., 124., 979., 430., 1073., 146., 111., 650.])
pattern1 = torch.tensor([430., 1073., 146.])
# Поиск совпадений шаблонов с точным сопоставлением
start_indices = torch.match(pattern1, template, mismatch_cnt=0, axis=0)
print(start_indices) # Возвращает tensor([3])
Функция torch.match поддерживает:
- Точное сопоставление (0 несоответствий)
- Приблизительное сопоставление с указанной допустимостью несоответствий
- Поиск шаблонов вдоль указанных осей
Сопоставление последовательностей с помощью пользовательских функций
Для более сложных числовых шаблонов можно реализовать пользовательские функции сопоставления:
import torch
def find_pattern_indices(data, pattern, tolerance=1e-6):
"""Поиск индексов, где шаблон встречается в тензоре данных"""
pattern_len = len(pattern)
data_len = len(data)
if pattern_len > data_len:
return torch.tensor([], dtype=torch.long)
# Сдвиг окна по данным
matches = []
for i in range(data_len - pattern_len + 1):
window = data[i:i+pattern_len]
if torch.allclose(window, pattern, atol=tolerance):
matches.append(i)
return torch.tensor(matches, dtype=torch.long)
# Пример использования
data = torch.tensor([1.0, 2.0, 3.0, 2.0, 3.0, 4.0, 5.0])
pattern = torch.tensor([2.0, 3.0, 4.0])
indices = find_pattern_indices(data, pattern)
print(indices) # Возвращает tensor([3])
Использование torch.nn.utils.rnn для операций с последовательностями
Для сопоставления с образцом на основе последовательностей могут быть полезны утилиты RNN PyTorch:
import torch
import torch.nn.utils.rnn as rnn_utils
# Создание заполненных последовательностей из шаблонов переменной длины
sequences = [
torch.tensor([1.0, 2.0, 3.0]),
torch.tensor([2.0, 3.0]),
torch.tensor([3.0, 4.0, 5.0, 6.0])
]
padded = rnn_utils.pad_sequence(sequences, batch_first=True, padding_value=0)
print(padded)
Продвинутые техники сопоставления с образцом
Обнаружение шаблонов на основе свертки
Для обнаружения конкретных числовых последовательностей в многомерных массивах:
import torch
import torch.nn.functional as F
def find_pattern_2d(data_tensor, pattern_tensor):
"""Использование свертки для поиска 2D-шаблонов в тензоре"""
# Изменение формы для свертки
data_reshaped = data_tensor.unsqueeze(0).unsqueeze(0) # Добавление размерностей пакета и канала
pattern_reshaped = pattern_tensor.unsqueeze(0).unsqueeze(0)
# Использование взаимной корреляции для поиска совпадений
correlation = F.conv2d(data_reshaped, pattern_reshaped)
matches = (correlation == pattern_tensor.numel()).squeeze()
return matches
# Пример
data = torch.tensor([
[1, 2, 3, 4],
[2, 3, 4, 5],
[3, 4, 5, 6]
])
pattern = torch.tensor([[2, 3], [3, 4]])
matches = find_pattern_2d(data, pattern)
print(matches) # Показывает позиции, где встречается шаблон
Статистическое сопоставление с образцом
Для шаблонов, основанных на статистических свойствах, а не на точных значениях:
import numpy as np
def find_statistical_pattern(data, window_size=3, threshold=0.8):
"""Поиск окон с похожими статистическими свойствами"""
means = []
stds = []
# Расчет статистики скользящего окна
for i in range(len(data) - window_size + 1):
window = data[i:i+window_size]
means.append(np.mean(window))
stds.append(np.std(window))
# Поиск похожих шаблонов
means = np.array(means)
stds = np.array(stds)
# Сравнение каждого окна с другими
similarity_matrix = np.zeros((len(means), len(means)))
for i in range(len(means)):
for j in range(len(means)):
if i != j:
mean_diff = abs(means[i] - means[j]) / (abs(means[i]) + abs(means[j]) + 1e-8)
std_diff = abs(stds[i] - stds[j]) / (abs(stds[i]) + abs(stds[j]) + 1e-8)
similarity = 1 - (mean_diff + std_diff) / 2
similarity_matrix[i, j] = similarity
# Поиск высокопохожих шаблонов
return np.where(similarity_matrix > threshold)
Рекомендации по производительности
Советы по производительности для NumPy
- Векторизация: Всегда отдавайте предпочтение векторизованным операциям вместо циклов Python
- Представления памяти: Используйте представления памяти для больших массивов, чтобы избежать копирования
- Типы данных: Используйте подходящие типы данных (например,
np.float32вместоnp.float64для точности, не требующей полной 64-битной)
Советы по производительности для PyTorch
- Ускорение GPU: Перемещайте тензоры на GPU для масштабного сопоставления с образцом
- Пакетная обработка: Обрабатывайте несколько шаблонов одновременно
- Отслеживание градиентов: Отключайте градиенты при использовании сопоставления с образцом для вывода
# Эффективное сопоставление с образцом на основе GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
data = data.to(device)
pattern = pattern.to(device)
with torch.no_grad(): # Отключение градиентов для вывода
results = torch.match(pattern, data, mismatch_cnt=0, axis=0)
Практические примеры
Пример 1: Обнаружение шаблонов цен на акции
import torch
import numpy as np
def detect_candlestick_patterns(prices, volume=None):
"""Обнаружение распространенных свечных шаблонов в данных о ценах"""
prices = torch.tensor(prices, dtype=torch.float32)
# Шаблон Доджи (открытие ≈ закрытие)
doji_indices = []
for i in range(1, len(prices) - 1):
if abs(prices[i] - prices[i-1]) < 0.01 * prices[i]:
doji_indices.append(i)
# Шаблон поглощения
engulfing_indices = []
for i in range(1, len(prices) - 1):
current_body = abs(prices[i] - prices[i-1])
previous_body = abs(prices[i-1] - prices[i-2])
if current_body > 1.5 * previous_body:
engulfing_indices.append(i)
return {
'doji': torch.tensor(doji_indices),
'engulfing': torch.tensor(engulfing_indices)
}
# Пример использования
stock_prices = [100.1, 100.2, 100.05, 100.3, 100.8, 101.2, 101.15]
patterns = detect_candlestick_patterns(stock_prices)
print(f"Шаблоны Доджи на индексах: {patterns['doji']}")
print(f"Шаблоны поглощения на индексах: {patterns['engulfing']}")
Пример 2: Обнаружение шаблонов в аудиосигнале
import torch
import numpy as np
def find_audio_silences(audio_data, threshold=0.01, min_duration=100):
"""Поиск тихих сегментов в аудиоданных"""
audio_tensor = torch.tensor(audio_data, dtype=torch.float32)
amplitude = torch.abs(audio_tensor)
# Поиск тихих регионов
is_silent = amplitude < threshold
# Группировка последовательных тихих выборок
changes = torch.diff(is_silent.int(), prepend=torch.tensor([0]))
silence_starts = torch.where(changes == 1)[0]
silence_ends = torch.where(changes == -1)[0]
# Фильтрация по минимальной длительности
valid_silences = []
for start, end in zip(silence_starts, silence_ends):
if (end - start) >= min_duration:
valid_silences.append((start, end))
return valid_silences
# Пример использования
audio_signal = np.random.normal(0, 0.5, 10000) # Случайный аудиосигнал
# Добавление некоторых тихих регионов
audio_signal[1000:1200] = 0.001
audio_signal[5000:5100] = 0.001
silences = find_audio_silences(audio_signal)
print(f"Найдено {len(silences)} тихих регионов")
for start, end in silences:
print(f"Тишина с {start} по {end} выборок")
Пример 3: Обнаружение аномалий во временных рядах
import torch
import numpy as np
def detect_anomalies(data, window_size=10, threshold=3.0):
"""Обнаружение аномалий с использованием скользящего z-оценки"""
data_tensor = torch.tensor(data, dtype=torch.float32)
anomalies = []
for i in range(window_size, len(data_tensor)):
window = data_tensor[i-window_size:i]
mean = torch.mean(window)
std = torch.std(window)
if std > 0:
z_score = (data_tensor[i] - mean) / std
if abs(z_score) > threshold:
anomalies.append(i)
return torch.tensor(anomalies)
# Пример использования
time_series = np.concatenate([
np.random.normal(100, 5, 1000), # Нормальные данные
np.random.normal(200, 10, 50), # Аномальные данные
np.random.normal(100, 5, 1000) # Возврат к норме
])
anomalies = detect_anomalies(time_series)
print(f"Обнаруженные аномалии на индексах: {anomalies}")
Источники
- Документация NumPy fromregex
- Stack Overflow: Сопоставление шаблонов регулярных выражений в массивах NumPy
- GitHub Issue PyTorch: Сопоставление с образцом
- Stack Overflow: Создание тензоров с конкретными шаблонами
- Stack Overflow: numpy.where на массиве строк с использованием регулярных выражений
- Stack Overflow: Логика регулярных выражений в массиве numpy/torch
- Документация PyTorch torch.match
- W3Resource NumPy fromregex
Заключение
Сопоставление с образцом числовых последовательностей в стиле регулярных выражений в массивах NumPy и PyTorch можно реализовать с помощью нескольких встроенных подходов:
- NumPy: Несмотря на отсутствие прямой поддержки регулярных выражений для числовых данных, можно использовать векторизованные операции, математические сравнения или функцию
fromregexдля данных на основе файлов - PyTorch: Предоставляет встроенную функцию
torch.matchдля сопоставления с образцом с необязательной допустимостью несоответствий, а также пользовательские реализации с использованием свертки и статистических методов - Производительность: Обе библиотеки поддерживают ускорение GPU для масштабного сопоставления с образцом при использовании PyTorch
- Гибкость: Математические операции обеспечивают больший контроль, чем традиционные регулярные выражения для числовых шаблонов, позволяя допускать сопоставление на основе допусков и обнаружение статистических шаблонов
В большинстве случаев функция torch.match PyTorch предоставляет наиболее прямой встроенный подход к числовому сопоставлению с образцом, в то время как пользователи NumPy могут реализовывать эффективные пользовательские решения с использованием векторизованных операций и математических сравнений.