我注意到我的question的早期版本建议使用查询,但我有唯一的数据框,它们没有相同的列名。我想编写这个公式而不用for循环,只用apply函数:
这是初始化的变量。 mu =μ,其他变量如下:
mu=pd.DataFrame(0, index=['A','B','C'], columns=['x','y'])
pij=pd.DataFrame(np.random.randn(500,3),columns=['A','B','C'])
X=pd.DataFrame(np.random.randn(500,2),columns=['x','y'])
接下来,我可以使用嵌套的for循环来解决这个问题
for j in range(len(mu)):
for i in range(len(X)):
mu.ix[j,:]+=pij.ix[i,j]*X.ix[i,['x','y']]
mu.ix[j,:]=(mu.ix[j,:])/(pij.ix[:,j].sum())
mu
x y
A 0.147804 0.169263
B -0.299590 -0.828494
C -0.199637 0.363423
我的问题是,是否可以不使用嵌套的for循环,甚至删除一个for循环来解决这个问题。我做了微弱的尝试无济于事。
即使我最初的尝试也会产生多个NaN。
答案 0 :(得分:1)
您粘贴的代码表示您认为公式左侧mu的索引为char *readcmd (char *buf, size_t max, FILE *fp)
{
if (!buf) return NULL; /* validate buf not NULL */
char *p = NULL;
int scncode[5] = {0}; /* scncode and sz to trap ctrl+l */
size_t sz = 0;
/* read input from fp, return NULL on EOF */
if (!(p = fgets (buf, max, fp)))
return NULL;
/* find '\n' or nul-terminating char, set len */
for (; *p && *p != '\n'; p++) {}
sz = p - buf;
/* if not '\n' - short read occurred, read/discard remaining */
if (*p != '\n')
{
int c;
fprintf (stderr, "error: line too long, exceeds %zu chars.\n", max);
/* read/discard chars reamining in buffer to '\n' */
while ((c = fgetc (fp)) != '\n' && c != EOF) {}
return NULL;
}
*p = 0; /* overwrite '\n' with nul-terminating char */
memcpy (scncode, buf, sz > 5 ? 5 : sz); /* fill scancode with buffer */
/* check byte/multibyte char against scancode */
if (scncode[0] == 12) fprintf (stderr, "==> [ctrl + l (ell)] pressed.\n");
return buf;
}
,因此我假设情况属实。
此外,由于您为示例生成了随机矩阵,我的结果将与您的结果不同,但我检查了您的粘贴代码与我生成的矩阵上的代码结果相同。
公式的RHS的分子可以使用适当的transpose和matrix multiplication来计算:
j
分母只是summing over columns:
>>> num = pij.transpose().dot(X)
>>> num
x y
A -30.352924 -22.405490
B 14.889298 -16.768464
C -24.671337 9.092102
然后"分裂"是element-wise division by column:
>>> denom = pij.sum()
>>> denom
A 23.460325
B 20.106702
C -46.519167
dtype: float64
答案 1 :(得分:0)
我首先将pij
标准化然后用X取内部产品。公式如下:
mu = (pij / pij.sum()).T.dot(X)