如何使用C#在数据点列表中识别所有峰值与谷值
Hey Dan, sounds like you’ve put in a solid week of work getting your CSV data loaded into arrays—great job getting that far! Let’s walk through how to tackle peak and valley detection, since that’s where you’re stuck right now.
First, let’s align on definitions: a peak is a data point larger than its immediate left and right neighbors, while a valley is smaller than both. We’ll also handle edge cases (the first and last points) since they only have one neighbor to compare against.
Option 1: Simple Iterative Check (Easy to Tweak)
If you prefer a straightforward, readable approach, loop through your array and compare each point to its neighbors. Here’s a Python example using numpy arrays (matching your list-to-array workflow):
import numpy as np def find_peaks_valleys(data): peaks = [] valleys = [] n = len(data) # Check middle points first for i in range(1, n - 1): current = data[i] left = data[i-1] right = data[i+1] if current > left and current > right: peaks.append((i, current)) # Store index and value elif current < left and current < right: valleys.append((i, current)) # Handle edge points (first and last elements) if n >= 2: # First point if data[0] > data[1]: peaks.append((0, data[0])) elif data[0] < data[1]: valleys.append((0, data[0])) # Last point if data[-1] > data[-2]: peaks.append((n-1, data[-1])) elif data[-1] < data[-2]: valleys.append((n-1, data[-1])) return peaks, valleys # Example usage with your loaded array # Assume your CSV data is stored in a numpy array called csv_data peaks, valleys = find_peaks_valleys(csv_data) print("Peaks (index, value):", peaks) print("Valleys (index, value):", valleys)
Option 2: Numpy Diff Method (Faster for Large Datasets)
For bigger datasets, use numpy’s vectorized operations to speed things up. We’ll use np.diff() to calculate changes between consecutive points, then look for sign shifts that signal peaks or valleys:
import numpy as np def find_peaks_valleys_np(data): diff = np.diff(data) n = len(diff) # Peaks: difference shifts from positive to negative peak_indices = np.where((diff[:-1] > 0) & (diff[1:] < 0))[0] + 1 # Valleys: difference shifts from negative to positive valley_indices = np.where((diff[:-1] < 0) & (diff[1:] > 0))[0] + 1 # Map indices to their values peaks = list(zip(peak_indices, data[peak_indices])) valleys = list(zip(valley_indices, data[valley_indices])) # Optional: Add edge checks if needed if data[0] > data[1]: peaks.insert(0, (0, data[0])) elif data[0] < data[1]: valleys.insert(0, (0, data[0])) if data[-1] > data[-2]: peaks.append((len(data)-1, data[-1])) elif data[-1] < data[-2]: valleys.append((len(data)-1, data[-1])) return peaks, valleys
Bonus: Handling Noisy Data
If your CSV data has small random fluctuations, smooth it first to avoid detecting irrelevant tiny peaks/valleys. A simple moving average works well:
# Smooth data with a 3-point moving average (adjust window size as needed) window_size = 3 smoothed_data = np.convolve(data, np.ones(window_size)/window_size, mode='valid') # Note: Smoothing reduces array length by window_size - 1, adjust indices accordingly
Quick Testing Tips
- Start with a small sample array (like
[1,3,2,5,1,4,0]) to verify the functions work as expected. - Decide if you need to include edge points—some projects ignore them if they don’t have full neighbor context.
Hope this gets you unstuck! Let me know if you need to adjust this for your specific dataset structure.
内容的提问来源于stack exchange,提问作者Dan King

