Python Data Frame How to Find the Local Maximum in a 2D Array

Get coordinates of local maxima in 2D array above certain value

import numpy as np
import scipy
import scipy.ndimage as ndimage
import scipy.ndimage.filters as filters
import matplotlib.pyplot as plt

fname = '/tmp/slice0000.png'
neighborhood_size = 5
threshold = 1500

data = scipy.misc.imread(fname)

data_max = filters.maximum_filter(data, neighborhood_size)
maxima = (data == data_max)
data_min = filters.minimum_filter(data, neighborhood_size)
diff = ((data_max - data_min) > threshold)
maxima[diff == 0] = 0

labeled, num_objects = ndimage.label(maxima)
slices = ndimage.find_objects(labeled)
x, y = [], []
for dy,dx in slices:
x_center = (dx.start + dx.stop - 1)/2
x.append(x_center)
y_center = (dy.start + dy.stop - 1)/2
y.append(y_center)

plt.imshow(data)
plt.savefig('/tmp/data.png', bbox_inches = 'tight')

plt.autoscale(False)
plt.plot(x,y, 'ro')
plt.savefig('/tmp/result.png', bbox_inches = 'tight')

Given data.png:

enter image description here

the above program yields result.png with threshold = 1500. Lower the threshold to pick up more local maxima:

enter image description here

References:

  • J.F. Sebastian counts nuclei
  • Joe Kington finds paw prints
  • Ivan finds local maximums

How to apply Max function between rows on 2D list in pandas grouped dataframe

df = (
df.groupby("grouping_val")["data"]
.apply(lambda x: [[*map(max, zip(*subl))] for subl in zip(*x)])
.reset_index()
)
print(df)

Prints:

  grouping_val               data
0 a [[1, 1], [1, 1]]
1 b [[2, 4], [4, 5]]

Pandas finding local max and min

Assuming that the column of interest is labelled data, one solution would be

df['min'] = df.data[(df.data.shift(1) > df.data) & (df.data.shift(-1) > df.data)]
df['max'] = df.data[(df.data.shift(1) < df.data) & (df.data.shift(-1) < df.data)]

For example:

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

# Generate a noisy AR(1) sample
np.random.seed(0)
rs = np.random.randn(200)
xs = [0]
for r in rs:
xs.append(xs[-1]*0.9 + r)
df = pd.DataFrame(xs, columns=['data'])

# Find local peaks
df['min'] = df.data[(df.data.shift(1) > df.data) & (df.data.shift(-1) > df.data)]
df['max'] = df.data[(df.data.shift(1) < df.data) & (df.data.shift(-1) < df.data)]

# Plot results
plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')
df.data.plot()

enter image description here

How can I take a 2d array and then take every row and collapse it into the index of the maximum number?

Since you tagged numpy, try with argmax and take_along axis:

# convert to numppy array if not already is
arr = np.array(arr)

idx = np.argmax(arr, axis=1)[..., None] # the index of row maxmimum
np.hstack([idx, np.take_along_axis(arr, idx, axis=1)])


Related Topics



Leave a reply



Submit