Reputation: 1921
I have a pandas
DataFrame
with rows representing a symmetric matrix component.
sxx syy szz sxy syz sxz
NodeID time
1500000 20921.0 2504729.0 -16524560.0 -3966213.0 5058878.0 8026349.0 390275.7
20923.0 2541577.0 -16459500.0 -3930280.0 5047995.0 8019404.0 393201.3
20925.0 2582004.0 -16384690.0 -3891037.0 5035703.0 8011226.0 396850.2
20927.0 2618859.0 -16313310.0 -3855520.0 5024095.0 8003384.0 400578.7
20933.0 2703961.0 -16133460.0 -3773937.0 4995101.0 7985394.0 411183.2
The matrix will look like the following.
[[sxx, sxy, sxz],
[sxy, syy, syz],
[sxz, syz, szz]]
What is the fastest way to calculate the eigenvalue from each row?
I tried 'applying' np.linalg.eigvalsh
on every row. However, it takes quite long when I have close to a million lines.
Edit
To give the complete context, I should also mention that this DataFrame
is part of an object definition. object.df
is the DataFrame
. Below is the related code.
def s1(self):
"""Returns the first principal stress for every node every timepoint"""
return self.df.apply(principal, axis=1, label="s1")
def principal(s, label):
principals = np.linalg.eigvalsh(
np.array(
[s.sxx, s.sxy, s.sxz, s.sxy, s.syy, s.syz, s.sxz, s.syz, s.szz]
).reshape(3, 3)
)
if label.lower() == "s3":
return principals[0]
elif label.lower() == "s2":
return principals[1]
elif label.lower() == "s1":
return principals[2]
else:
raise ValueError("Invalid Input, choose from s1, s2, or s3.")
Upvotes: 2
Views: 1681
Reputation: 4343
You can set the order of the columns to generate a view and then pass it to an array using .values
(faster than np.array(..)
), then apply eigvalsh
to an (n, 3, 3)
array:
values = df[['sxx', 'sxy', 'sxz', 'sxy', 'syy', 'syz', 'sxz', 'syz', 'szz']].values.reshape(-1,3))
eigh = eigvalsh(values.reshape((-1, 3, 3)))
eigh
>>array([[-21253030.07083309, -1397298.11167328, 4664284.18250638],
[-21184732.23304478, -1361435.36228467, 4697964.59532944],
[-21106512.77176102, -1322433.70013306, 4735223.47189408],
[-21032246.72681734, -1287171.41922922, 4769447.14604654],
[-20847979.70886149, -1205613.19093403, 4850156.89979552]])
Upvotes: 2