我有一个大小为2441x1441(A)的熊猫数据框,在上三角形中为零-诊断具有值。我想将其每一列乘以长度为2441(B)的向量。棘手的部分是,我想要A的第一个非零值乘以B的第一个值(以及A的第二个值与B的第二个值,依此类推)。这应该在A的所有列上发生,并导致另一个数据帧C。
A=pd.DataFrame(
[[1, 0, 0],
[3, 4, 0],
[6, 7, 8]])
B=np.array([1,2,3,4]).T
结果将是
C=[ 1, 0, 0,
6, 4, 0,
18, 14, 8]
我创建了一个for循环,可以在其中循环访问每个值
for x in range(0,len(B)):
C = (A.iloc[192+x:,:].T*B[0:len(B)-x]).T
但是,这非常慢,我需要在不同的数据集上多次重复此操作。有没有一种很好的,Python化的向量化方法?
答案 0 :(得分:1)
好的,那么如何从您的B向量创建一个与您想要的形状匹配的数组呢? 以这种方式对其进行转换后,可以执行逐元素乘法,所有正确的值都将对齐。
A = np.array([[1, 0, 0],
[3, 4, 0],
[6, 7, 8]])
B = np.array([1,2,3,4])
mB = B[:A.shape[0]]
shift = B[:A.shape[0]]
for b in range(0,A.shape[0]):
shift = np.roll(shift ,1)
mB = np.append(mB, shift)
mB.resize(A.shape)
np.tril(mB.T)
>>>> array([[1, 0, 0],
[2, 1, 0],
[3, 2, 1]])
在上面,我强制右上角的三角形为零,但是由于您的A向量在那些位置已经为零,所以在乘法数组的这些位置中将要具有的值并不重要-因此,np.tril
步骤并不是必需的。
无论如何,无论您的偏好如何,一旦有了该表格(可能比上面使用的方法更好的方式来获得该表格),那么您就可以np.multiply
这两个对象相乘了对齐的元素。
np.multiply(A, np.tril(mB.T))
>>>> array([[ 1, 0, 0],
[ 6, 4, 0],
[18, 14, 8]])
答案 1 :(得分:1)
这是一种方法:
您可以从B
创建下三角矩阵,方法是在每一列上对向量B
进行修整和零填充,使其上三角部分全为零。
因此,从本质上讲,您是在复制矩阵乘法运算。然后,您只需使用A*new_B
或np.multiply(A,new_B)
将两个矩阵逐个元素相乘即可。
new_b = np.array([list(np.pad(B[:-i] if i != 0 else B,(i,0), 'constant'))
for i in range(len(B))]).T[:len(A),:len(A)]
print(new_b)
array([[1, 0, 0],
[2, 1, 0],
[3, 2, 1]])
print(new_b*A)
array([[ 1, 0, 0],
[ 6, 4, 0],
[18, 14, 8]])
答案 2 :(得分:1)
使用np.fromfunction
定义一个矩阵,其条目为所需的乘数。例如,如果
A = np.array([[1, 0, 0],
[3, 4, 0],
[6, 7, 8]])
然后
B = np.clip(np.fromfunction(lambda i, j: i-j+1, A.shape), 0, None)
会给你
B = np.array([[1, 0, 0],
[2, 1, 0],
[3, 2, 1]])
,然后您想要的结果只是A
和B
的元素乘积:
C = A * B
收益
C = np.array([[1, 0, 0],
[6, 4, 0],
[18, 14, 8]])
实际上,由于您的A
是较低三角形的,因此您可以在np.clip
的定义中将呼叫删除到B
,并获得相同的C
。
编辑:我对这个问题有误解。如果OP中的B
(由于我已经使用过b
,所以我叫它B
)不是自然数序列,则可以
B = np.tril(
np.fromfunction(
lambda i, j: b[np.clip((i-j).astype(int), 0, b.shape[0])],
A.shape))
例如,如果
b = np.array([2, 3, 1, 4])
那么你会得到
B = np.array([[2, 0, 0],
[3, 2, 0],
[1, 3, 2]])