如何用python中的条件进行矩阵乘法?
How to perform Matrix multiplication with conditions in python?
我在数据帧上使用矩阵乘法并将其转置 df@df.T
所以如果我有一个 df 看起来像:(低于 1 表示对象有 属性 而 0 表示没有):
Object Property1 Property2 Property3
A 1 1 1
B 0 1 1
C 1 0 0
使用 df@df.T 给我:
A B C
A 3 2 1
B 2 2 0
C 1 0 1
这可以被认为是一个矩阵,显示每个对象与另一个对象共有多少属性。
我现在想修改问题,而不是二进制指示对象是否具有 属性,属性列显示 属性 的级别。所以新的 df 看起来像:(属性值 1、2、3 下方显示其级别。但 0 表示没有 属性)
Object Property1 Property2 Property3
A 3 2 1
B 0 2 3
C 2 0 0
我想应用矩阵乘法,但更改了 'common' 属性的定义。如果 属性 的级别在另一个 属性.
的 +-1 范围内,则两个对象将只有一个共同的 属性
结果如下所示:
A B C
A 3 1 1
B 1 2 0
C 1 0 1
注意A和B共有的属性个数从2变成了1。这是因为属性A和B之间的3个不在+-1级之内。此外,0 仍然意味着该对象没有 属性,因此 A 和 C 仍然有 1 个 属性(C 的 属性 3 为 0)。
如何在 Python 中实现此目的?
这可以通过修改两个数据帧的矩阵乘法来完成
代码
# DataFrame Matrix Multiplication
# i.e. equivalent to df1@df2
def df_multiply(df_a, df_b):
'''
Matrix multiplication of values in two DataFrames
Returns a DataFrame whose index and column are
from the df_a
'''
a = df_a.values
b = df_b.values
zip_b = zip(*b)
zip_b = list(zip_b)
zip_b = b
result = [[sum(ele_a*ele_b for ele_a, ele_b in zip(row_a, col_b))
for col_b in zip_b] for row_a in a]
return pd.DataFrame(data=result, index=df_a.index, columns=df_a.index)
# Modify df_multiply for desired result
def df_multiply_modified(df_a, df_b):
'''
Modified Matrix multiplication of values in two DataFrames to create desired result
Returns a DataFrame whose index and
column are from the df_a
'''
a = df_a.values
b = df_b.values
zip_b = zip(*b)
zip_b = list(zip_b)
# sum 1 when difference <= 1 and
# values are non-zero
# i.e. ele_a and ele_b and abs(ele_a-ele_b) <=1
result = [[sum(1 if ele_a and ele_b and abs(ele_a-ele_b) <=1 else 0 for ele_a, ele_b in zip(row_a, col_b))
for col_b in zip_b] for row_a in a]
return pd.DataFrame(data=result, index=df_a.index, columns=df_a.index)
用法
原乘法
df = pd.DataFrame({'Object':['A', 'B', 'C'],
'Property1':[1, 0, 1],
'Property2':[1, 1, 0],
'Property3':[1, 1, 0]})
df.set_index('Object', inplace = True)
print(df_multiply(df, df.T)
# Output (same as df@df.T):
Object A B C
Object
A 3 2 1
B 2 2 0
C 1 0 1
修正乘法
# Use df_multiply_modified
df = pd.DataFrame({'Object':['A', 'B', 'C'],
'Property1':[3, 0, 2],
'Property2':[2, 2, 0],
'Property3':[1, 3, 0]})
df.set_index('Object', inplace = True)
print(df_multiply_modified(df, df.T)
# Output (same as desired)
Object A B C
Object
A 3 1 1
B 1 2 0
C 1 0 1
我在数据帧上使用矩阵乘法并将其转置 df@df.T
所以如果我有一个 df 看起来像:(低于 1 表示对象有 属性 而 0 表示没有):
Object Property1 Property2 Property3
A 1 1 1
B 0 1 1
C 1 0 0
使用 df@df.T 给我:
A B C
A 3 2 1
B 2 2 0
C 1 0 1
这可以被认为是一个矩阵,显示每个对象与另一个对象共有多少属性。
我现在想修改问题,而不是二进制指示对象是否具有 属性,属性列显示 属性 的级别。所以新的 df 看起来像:(属性值 1、2、3 下方显示其级别。但 0 表示没有 属性)
Object Property1 Property2 Property3
A 3 2 1
B 0 2 3
C 2 0 0
我想应用矩阵乘法,但更改了 'common' 属性的定义。如果 属性 的级别在另一个 属性.
的 +-1 范围内,则两个对象将只有一个共同的 属性结果如下所示:
A B C
A 3 1 1
B 1 2 0
C 1 0 1
注意A和B共有的属性个数从2变成了1。这是因为属性A和B之间的3个不在+-1级之内。此外,0 仍然意味着该对象没有 属性,因此 A 和 C 仍然有 1 个 属性(C 的 属性 3 为 0)。
如何在 Python 中实现此目的?
这可以通过修改两个数据帧的矩阵乘法来完成
代码
# DataFrame Matrix Multiplication
# i.e. equivalent to df1@df2
def df_multiply(df_a, df_b):
'''
Matrix multiplication of values in two DataFrames
Returns a DataFrame whose index and column are
from the df_a
'''
a = df_a.values
b = df_b.values
zip_b = zip(*b)
zip_b = list(zip_b)
zip_b = b
result = [[sum(ele_a*ele_b for ele_a, ele_b in zip(row_a, col_b))
for col_b in zip_b] for row_a in a]
return pd.DataFrame(data=result, index=df_a.index, columns=df_a.index)
# Modify df_multiply for desired result
def df_multiply_modified(df_a, df_b):
'''
Modified Matrix multiplication of values in two DataFrames to create desired result
Returns a DataFrame whose index and
column are from the df_a
'''
a = df_a.values
b = df_b.values
zip_b = zip(*b)
zip_b = list(zip_b)
# sum 1 when difference <= 1 and
# values are non-zero
# i.e. ele_a and ele_b and abs(ele_a-ele_b) <=1
result = [[sum(1 if ele_a and ele_b and abs(ele_a-ele_b) <=1 else 0 for ele_a, ele_b in zip(row_a, col_b))
for col_b in zip_b] for row_a in a]
return pd.DataFrame(data=result, index=df_a.index, columns=df_a.index)
用法
原乘法
df = pd.DataFrame({'Object':['A', 'B', 'C'],
'Property1':[1, 0, 1],
'Property2':[1, 1, 0],
'Property3':[1, 1, 0]})
df.set_index('Object', inplace = True)
print(df_multiply(df, df.T)
# Output (same as df@df.T):
Object A B C
Object
A 3 2 1
B 2 2 0
C 1 0 1
修正乘法
# Use df_multiply_modified
df = pd.DataFrame({'Object':['A', 'B', 'C'],
'Property1':[3, 0, 2],
'Property2':[2, 2, 0],
'Property3':[1, 3, 0]})
df.set_index('Object', inplace = True)
print(df_multiply_modified(df, df.T)
# Output (same as desired)
Object A B C
Object
A 3 1 1
B 1 2 0
C 1 0 1