함형건
함형건

Reputation: 1

Python code for converting two mode matrix data into one-mode

Being a novice on Python, I am wondering if there is any way possible I can convert two mode matrix data into one mode using Python code.

This is to create a data for social network analysis, and I am looking for a way to use Pandas and Python to create such a script.

Provided I have two mode data llke this,

     workshop1     workshop2     workshop3    workshop4

A 1 0 1 1

B 0 1 1 0

C 1 1 1 0

D 0 0 0 1

I need to convert that into one mode matrix like this.

           A        B        C          D

A 4 1 2 1

B 1 4 2 0

C 2 2 4 0

D 1 0 0 4

A,B,C,D are names of persons registered for workshops, "1" means the specific person signed up for the workshop.

One-mode matrix data indicate how many times they are supposed to meet each other at workshops. For example, A and C are expected to meet two times at workshop 1 and workshop3.

Thank you any advise or help in advance!

Upvotes: 0

Views: 776

Answers (1)

Falko
Falko

Reputation: 17877

NumPy solution:

According to this tutorial you can simply multiply the matrix with it's transpose. Using the NumPy functions dot() and transpose() (or the short form T) you end up with the following code:

import numpy as np

M = np.array([
    [1,0,1,1],
    [0,1,1,0],
    [1,1,1,0],
    [0,0,0,1]])

print M.dot(M.T)

Output:

[[3 1 2 1]
 [1 2 2 0]
 [2 2 3 0]
 [1 0 0 1]]

Only the diagonals are not 4 as you requested. In contrast they contain the number of workshops a person attended. You can easily fix that with np.fill_diagonal(A, 4) with A being the one-mode matrix.

No-NumPy solution:

In case you don't want to use NumPy, you can adapt a standard matrix multiplication to the special case of "R = M*M^T":

m = len(M)
n = len(M[0])
R = [[0 for i in range(m)] for j in range(m)]
for i in range(m):
    for j in range(m):
        for k in range(n):
            R[i][j] += M[i][k] * M[j][k]

Or the corresponding one-liner with 3 indices i, j and k:

R = [[sum(M[i][k] * M[j][k] for k in range(len(M[0]))) for i in range(len(M))] for j in range(len(M))]

Or directly iterating over rows of M:

R = [[sum(a * b for a, b in zip(A, B)) for B in M] for A in M]

Upvotes: 0

Related Questions