Reputation: 986
I have the following pandas.DataFrame object that provides the covariances between factors:
import pandas as pd
df = pd.DataFrame({"factor1": ["A", "A", "A", "B", "B", "C"],
"factor2": ["A", "B", "C", "B", "C", "C"],
"covar": [-1.2, -1, 2, 3.4, -4, 6.2]})
My objective is to reformat the DataFrame into a positive semi-definite covariance numpy.ndarray.
I have developed a working solution, however, it is painfully slow:
unique_factors = df.factor1.unique()
F = pd.DataFrame(columns=unique_factors, index=unique_factors)
for index, row in df.iterrows():
F.loc[row["factor1"], row["factor2"]] = row["covar"]**2
F.loc[row["factor2"], row["factor1"]] = row["covar"]**2 #inefficient
F = F.to_numpy()
The output of which is:
[[1.44 1.0 4.0 ]
[1.0 11.559999999999999 16.0 ]
[4.0 16.0 38.440000000000005]]
I am hoping that I can take advantage of numpy's native methods to accomplish my objective more efficiently. At the very least I would like to be able to remove the line commented #inefficient
and reflect the upper triangular matrix about the diagonal. Any help would be much appreciated.
Upvotes: 0
Views: 986
Reputation: 323226
In your case
s=df.pivot(*df.columns)**2
s=s.fillna(s.T)
Out[230]:
factor2 A B C
factor1
A 1.44 1.00 4.00
B 1.00 11.56 16.00
C 4.00 16.00 38.44
Upvotes: 2