简体   繁体   中英

In a Multi-index DataFrame, how to perform matrix multiplication for a subset of data?

The following code is a sample DataFrame. Now I need to have all the XYZ under Position to be multiplied by a rotation matrix, let's say 90deg around Z: [[1,0,0],[0,0,-1],[0,1,0]]

How to do this without using loops? Or as fewer loops as possible. Thanks in advance.

index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]],
                                   names=['year', 'Record'])
columns = pd.MultiIndex.from_product([['Point1', 'Point2'],['Position', 'Not-Important'], ['X', 'Y','Z']])

# mock some data
data = np.round(np.random.randn(4, 12), 1)
data[:, ::2] *= 10
data += 37

# create the DataFrame
hd = pd.DataFrame(data, index=index, columns=columns)
              Point1                                         Point2
            Position             Not-Important             Position             Not-Important
                   X     Y     Z             X     Y     Z        X     Y     Z             X     Y     Z
year Record
2013 1          26.0  38.1  42.0          35.0  37.0  37.2     35.0  36.9  28.0          37.2  58.0  37.0
     2          42.0  36.4  36.0          36.5  43.0  35.4     28.0  36.3  60.0          35.5  41.0  37.3
2014 1          47.0  36.6  32.0          37.9  58.0  37.7     25.0  36.5  21.0          38.6  33.0  36.3
     2          42.0  38.6  26.0          35.2  37.0  36.3     21.0  36.5  27.0          36.3  26.0  35.5

We have our transform matrix:

Z = np.array([[1,0,0],[0,0,-1],[0,1,0]])

Each row has two points but it also has values that are not important. We build a transform matrix with the desired rotation matrix for the points and the identity matrix for the other values, so that they remain unchanged.

# I'm sure there is a more elegant way of doing this
ZZ = np.zeros((12,12))
ZZ[0:3,0:3] = Z
ZZ[3:6,3:6] = np.eye(3)
ZZ[6:9,6:9] = Z
ZZ[9:12,9:12] = np.eye(3)

Now we are ready to rotate those points:

hd.transform(lambda x: np.matmul(ZZ, x), axis=1)

DataFrame.transform will call our function for every row (because the axis parameter is 1 ) and will pass a series with the values. Our function simply does the matrix multiplication between the transform matrix and the vector that corresponds to a row in the original DataFrame.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM