numpy 从数据透视表创建“距离” Dataframe

sqserrrh  于 2023-06-29  发布在  其他
关注(0)|答案(2)|浏览(77)

好的,我有一个关系表(认为某人有一个项目),我已经成功地将它旋转成一个布尔矩阵。我想进行下一步,找到任意两个给定用户之间的“距离”的矩阵。
我知道如果我想做一个一次性的距离,我基本上可以做到以下几点:

df = ...
df["val"] = 1

pivot = df.pivot(index="person", columns="hasa", values="val").fillna(0)

# compute one difference
(pivot["Alice"] - pivot["Carol"]).abs().sum()

我不知道如何从这里到一个完整的 Dataframe 。

初始表

| 哈萨| hasa |
| --| ------------ |
| 苹果| Apple |
| 香蕉| Banana |
| 胡萝卜| Carrot |
| 苹果| Apple |

数据透视表

| | 胡萝卜| Banana | Carrot |
| --|--|--| ------------ |
| 1| 0| 0| 0 |
| 1| 1| 0| 0 |
| 0| 0| 1| 1 |

目标表

| | 卡罗尔| Bob | Carol |
| --|--|--| ------------ |
| 0| 1| 2| 2 |
| 1| 0| 3| 3 |
| 2| 3| 0| 0 |

vbopmzt1

vbopmzt11#

你可以直接使用crosstab计算“枢轴”,然后使用默认的“欧几里得”度量计算与scipy.spatial.distance.cdist的距离,你只需要平方它:

from scipy.spatial.distance import cdist

pivot = pd.crosstab(df['person'], df['hasa'])

out = pd.DataFrame(cdist(pivot, pivot)**2,
                   index=pivot.index,
                   columns=pivot.index,
                  )

或者,您也可以使用corr和自定义函数进行第二步:

out = pivot.T.corr(lambda a,b: sum(a!=b))

或者手动使用numpy广播(对于大输入,内存很昂贵):

a = pivot.to_numpy()
out = (a[..., None] != a.T).sum(axis=1)

输出:

person  Alice  Bob  Carol
person                   
Alice     0.0  1.0    2.0
Bob       1.0  0.0    3.0
Carol     2.0  3.0    0.0
6qqygrtg

6qqygrtg2#

让我们从简单的开始。您可以通过创建另一个DataFrame来计算数据透视表中所有行之间的距离,该DataFrame将存储这些距离。这里的主要逻辑是遍历透视表的每一行并计算到每隔一行的距离。

# Create initial DataFrame
df = pd.DataFrame({
    'person': ['Alice', 'Bob', 'Carol', 'Bob'],
    'hasa': ['Apple', 'Banana', 'Carrot', 'Apple']
})

# Pivot DataFrame
pivot_df = pd.pivot_table(df, index='person', columns='hasa', aggfunc=len, fill_value=0)

# Create empty DataFrame for distances
distance_df = pd.DataFrame(index=pivot_df.index, columns=pivot_df.index)

# Fill DataFrame with distances
for person1 in pivot_df.index:
    for person2 in pivot_df.index:
        distance_df.loc[person1, person2] = (pivot_df.loc[person1] - pivot_df.loc[person2]).abs().sum()

现在,distance_df应该有正确的值。请注意,生成的DataFrame沿着主对角线对称(因为从Alice到Bob的距离与从Bob到Alice的距离相同)。主对角线用零填充(因为从人到自己的距离总是零)。

相关问题