import numpy as np
p0 = 4000.0 # N
freq = np.array((4, 5, 6, 7))*2*np.pi # rad/s
rho = np.array((177, 218, 300, 517))*1E-6 # m
theta = np.array((5, 8, 14, 29))*np.pi/180 # rad
The unknowns are $k$ an $m$, the matrix of coefficients follows from
$$ 1\cdot k - \omega_i^2\cdot m, \qquad i=1,\ldots,\text{no. of tests.}$$A = np.vstack((np.ones(len(freq)),-freq**2)).T
print(A)
The known term is given by
$$\frac{p_0}{\rho_i}\,\cos\theta_i, \qquad i=1,\ldots,\text{no. of tests.}$$b = p0*np.cos(theta)/rho
print(b/1E6, 'kN/mm')
We have (fortunately) an overdetermined linear system, we can solve it using a least squares approximation.
k, m = np.linalg.lstsq(A, b)[0]
wn = np.sqrt(k/m)
print(' k =', k)
print(' m =', m)
print('wn =', wn)
We can derive a formula for $\zeta$ using only one measurement, but we use all the measurements using again least squares (note that, in this case, the least squares estimate is just the mean value of the individual estimates).
Ones = np.ones(4)[:,None]
beta = freq/wn
zs = p0*np.sin(theta)/(rho*k)/(2*beta)
z = np.linalg.lstsq(Ones, zs)[0][0]
print(' Individual estimates of zeta, %:', zs*100)
print('Least Squares estimate of zeta, %:', z*100)