Python pandas.DataFrame上的成对行操作矩阵
我想创建一个数据帧中所有行对的操作结果矩阵 下面是我想要的一个例子:Python pandas.DataFrame上的成对行操作矩阵,python,pandas,numpy,dataframe,pairwise,Python,Pandas,Numpy,Dataframe,Pairwise,我想创建一个数据帧中所有行对的操作结果矩阵 下面是我想要的一个例子: df = pandas.DataFrame({'val': [ 2, 3, 5, 7 ], 'foo': ['f1', 'f2', 'f3', 'f4']}, index= ['n1', 'n2', 'n3', 'n4']) def op1(row1, row2): return row1['val'
df = pandas.DataFrame({'val': [ 2, 3, 5, 7 ],
'foo': ['f1', 'f2', 'f3', 'f4']},
index= ['n1', 'n2', 'n3', 'n4'])
def op1(row1, row2):
return row1['val']*row2['val']
def op2(row1, row2):
return f"{row1['foo']}{row2['foo']}"
def apply_op_to_all_row_pairs(df, op):
# what goes in here?
apply_op_to_all_row_pairs(df, op1)
# n1 n2 n3 n4
# n1 4 6 10 14
# n2 6 9 15 21
# n3 10 15 25 35
# n4 14 21 35 49
apply_op_to_all_row_pairs(df, op2)
# n1 n2 n3 n4
# n1 'f1f1' 'f1f2' 'f1f3' 'f1f4'
# n2 'f2f1' 'f2f2' 'f2f3' 'f2f4'
# n3 'f3f1' 'f3f2' 'f3f3' 'f3f4'
# n4 'f4f1' 'f4f2' 'f4f3' 'f4f4'
我见过很多依赖于计算距离矩阵的现有函数的解决方案,但我想要更通用的解决方案。
例如,
scipy.spatial.distance.pdist
执行我想要的格式,但只处理浮点数,不允许您按名称选择列(或者至少我不知道如何选择)。您可以使用广播numpy操作:
v = df.val.values[:, None] * df.val.values
v
array([[ 4, 6, 10, 14],
[ 6, 9, 15, 21],
[10, 15, 25, 35],
[14, 21, 35, 49]])
x = df.foo.values[:, None] + df.foo.values
x
array([['f1f1', 'f1f2', 'f1f3', 'f1f4'],
['f2f1', 'f2f2', 'f2f3', 'f2f4'],
['f3f1', 'f3f2', 'f3f3', 'f3f4'],
['f4f1', 'f4f2', 'f4f3', 'f4f4']], dtype=object)
转换为数据帧非常简单,只需调用构造函数:
pd.DataFrame(x, df.index, df.index)
n1 n2 n3 n4
n1 f1f1 f1f2 f1f3 f1f4
n2 f2f1 f2f2 f2f3 f2f4
n3 f3f1 f3f2 f3f3 f3f4
n4 f4f1 f4f2 f4f3 f4f4
这并没有以问题的形式完成函数,但它确实满足了我的要求。谢谢@蔡:听你这么说太好了!感谢您让我知道。为了澄清我最初的问题:一种单独定义行对操作的方法,每个行对操作都可以应用于数据帧。这与您给出的不同之处在于,函数定义(
foo+foo
)与广播混合在一起。完全分开的那一个很好,但对于我现在需要的,这是完全足够的。@Cai我理解你现在的要求。不幸的是,解耦成本很高,并且会导致性能大大降低。仅供参考。