【问题标题】:Pandas - Take bitwise similarly and calculate weighted mean based on thatPandas - 以类似方式按位计算加权平均值
【发布时间】:2019-06-11 01:43:08
【问题描述】:

我有一个像这样的 Pandas 数据框df1

  ID  col1 col2 col3
0  A   1    1    1
1  B   1    1    1
2  C   1    0    1
3  D   0    0    0
4  E   1    1    1
5  F   0    1    0
6  G   1    0    0
7  H   0    1    0

和另一个数据框df2 像这样:

  ID  col1 col2 col3 rating1  rating2
0  I   0    1    0     1        2
1  J   0    1    1     3        1
2  K   1    0    0     4        4
3  L   0    1    0     2        2

我需要找到df1 的每一行(ID 除外)与df2 中的相应行之间的相似性(x==y).sum(不是按位异或),并将该相似性用作计算平均值的权重df1 中所有 ID 的评分。

例如:

A 的最终评分应计算为:

rating1[A] = ( 1*1 + 2*3 + 1*4 + 1*2 ) / (1 + 2 + 1 + 1) = 13/5

在使用 df2 计算评分的相似性平均值后,我的输出应该是另一个数据框,其中包含 df1 中所有 ID 的评分。

输出数据框:

  ID rating1  rating2
0  A   13/5      2
1  B   13/5      2
... and so on till ID H

请帮助我使用 pandas 函数有效地做到这一点。我尝试通过遍历所有行来做到这一点,但 df1df2 都是非常大的表,而且需要很多时间。

提前致谢。


更新

@WeNYoBen 的回答是正确的。尽管在我的例子中,df1df2 的尺寸比我在这里作为示例显示的要高得多。

在第三行(@WeNYoBen 的回答)中,s 的尺寸将是 len(df1)*len(df2),在我的情况下它们都很大,并给我一个 MemoryError。是否有任何解决方法,从某种意义上说,我可以将df2 拆分为更小的部分并可以单独计算它们?

再次感谢。

【问题讨论】:

  • 我认为 A 和 B 应该有相同的评级吧?因为它们在 df1 中具有相同的值
  • 是的,检查更新版本。感谢您指出@WeNYoBen

标签: python pandas dataframe vector matrix-multiplication


【解决方案1】:

这更像是numpy 广播然后dot

s1=df1.iloc[:,1:].values
s2=df2.iloc[:,1:-2].values
s=np.sum(s1[:,None]==s2,-1)
df1['rating1']=s.dot(df2.rating1)/s.sum(1)
df1['rating2']=s.dot(df2.rating2)/s.sum(1)
df1
Out[623]: 
  ID  col1  col2  col3   rating1   rating2
0  A     1     1     1  2.600000  2.000000
1  B     1     1     1  2.600000  2.000000
2  C     1     0     1  3.666667  3.000000
3  D     0     0     0  2.428571  2.428571
4  E     1     1     1  2.600000  2.000000
5  F     0     1     0  2.111111  2.000000
6  G     1     0     0  3.000000  3.200000
7  H     0     1     0  2.111111  2.000000

【讨论】:

  • 感谢您的回答。但是我在第 3 行收到了 DeprecationWarning: elementwise comparison failed; this will raise an error in the future. This is separate from the ipykernel package so we can avoid doing imports until 警告。s1[:, None] 的形状是 (8, 1, 2),而 s2 的形状是 (N2, 2)。我是 Pandas 和 numpy 矩阵的新手,你能帮我解决这个错误吗?
  • @DevanshuSomani 啊我知道,更新,将_values 更改为值
  • 我这样做了,但仍然遇到同样的错误。 s1s2 具有相似的形状。 s1[:, None] 是做什么的?它已将 2d s1 转换为 3d。
  • 实际数据:print(s1.shape, s1[:,None].shape, s2.shape) (3764955, 79) (3764955, 1, 79) (5544, 79)
  • 我发现了我的错误。它实际上是一个 MemoryError,因为在我的情况下,s 变成了一个 3764955*5544 的 numpy 数组。您能否提出一些替代方案,以便我可以将其分成几部分并在不超过内存限制的情况下进行计算?
猜你喜欢
  • 2017-02-06
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
  • 2016-02-12
  • 2020-10-08
  • 2021-11-24
  • 2016-05-23
  • 2018-03-10
相关资源
最近更新 更多