如何在python中使用条件执行矩阵乘法?
我在数据帧上使用矩阵乘法,并将其转置为如何在python中使用条件执行矩阵乘法?,python,pandas,matrix-multiplication,Python,Pandas,Matrix Multiplication,我在数据帧上使用矩阵乘法,并将其转置为df@df.T 因此,如果我有一个df,它如下所示:(下面的1表示对象具有该属性,而0表示没有该属性): 使用df@df.T给我: A B C A 3 2 1 B 2 2 0 C 1 0 1 这可以看作是一个矩阵,显示每个对象与另一个对象有多少共同的属性 我现在想修改一个问题,在这个问题中,properties列显示的不是对象是否具有属性的二进制指示,而是该属性的级别。因此,新的df如下所示:(属性值1,2,3下方显示其级别
df@df.T
因此,如果我有一个df,它如下所示:(下面的1表示对象具有该属性,而0表示没有该属性):
使用df@df.T给我:
A B C
A 3 2 1
B 2 2 0
C 1 0 1
这可以看作是一个矩阵,显示每个对象与另一个对象有多少共同的属性
我现在想修改一个问题,在这个问题中,properties列显示的不是对象是否具有属性的二进制指示,而是该属性的级别。因此,新的df如下所示:(属性值1,2,3下方显示其级别。但0表示没有该属性)
我想应用矩阵乘法,但修改了“公共”属性的定义。只有当一个属性的级别在另一个属性的+-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)
修正乘法
谢谢“修改的乘法”的代码与您显示的一样工作,但运行“原始乘法”时的输出与您显示的不同。不过,修改后的乘法代码运行良好,因此它回答了这个问题。@TheloniusMonk——您提到的原始代码是不同的。您的数据帧与我显示的数据帧相同(包括索引列,即使用set_index)还是不同?如果是,它是如何生成的?我运行了你的代码,在那里你定义了函数和块“原始乘法”。产出似乎很高different@TheloniousMonk--你能给你的帖子添加代码,让我创建你在例子中展示的数据吗(也就是说,这通常是推荐给帖子的)。那么,我可以看出你所说的区别了。
A B C
A 3 1 1
B 1 2 0
C 1 0 1
# 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