有没有比嵌套的iterrows更快的方法?

2024-05-12 15:51:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我从一个pandas数据框中创建一对行,以基于每对行进行一些计算,并创建一个新的数据框

affinity = []
for prod1 in data3.iterrows():
        for prod2 in data3.iterrows():
           if prod1[0] != prod2[0]:
               pair = pd.concat([prod1[1],prod2[1]], axis=1)
               total = max(np.count_nonzero(pair, axis=0))
               match = pair[(pair.iloc[:, 0]==1) & (pair.iloc[:, 1]==1)]
               prob = match.shape[0] / total
               dat = [prod1[0],prod2[0],prob]
               affinity.append(dat)
affinity = pd.DataFrame(affinity)

有没有一种更快的方法来做同样的事情?除了行本身,我必须检查所有可能的对。我知道有itertools.product,但我不知道如何将它用于数据帧的行。我看到了一些只有列表的用例

输入样本:

       ticket1  ticket2  ticket3
class1      0         0        0
class2      0         1        0
class3      0         1        0

预期产出:

  col1   col2  col3
class1  class2  0.0
class2  class3  1.0
class3  class1  0.0

Tags: 数据infortotalpdaffinityaxispair
1条回答
网友
1楼 · 发布于 2024-05-12 15:51:43

这与协方差计算非常相似!让我们用numpy一步一步地做:

警告我假设您的数组中只有0和1,因为您检查的是与1和0的等式

data = data3.to_numpy()

match_matrix = data @ data.T 
# Matix multiplication : 
# match[i,j] = data[i][0]*data[j][0] + data[i][0]*data[j][0] + data[i][0]*data[j][0]

total_per_row = np.count_nonzero(data,axis=1) # can be replaced with sum

total_matrix = np.maximum(total_per_row[:,np.newaxis],total_per_row[np.newaxis,:])
# Broadcast and compare maximums:
# total_matrix[i,j] = max(total_per_row[i],total_per_row[j])


probability_matrix = match_matrix / total_matrix

现在有了矩阵形式的affinity!您可以将其加载回数据帧,然后stack使其看起来像您想要的输出,或者保持原样并显示一些相关矩阵

编辑:添加如何准确获得预期结果:

pd.DataFrame(
    np.where(
        np.triu(np.ones(probability_matrix.shape), k=1).astype(bool),
        np.nan_to_num(probability_matrix),
        np.nan,
    ),
    index=data3.index,
    columns=data3.index,
).stack().reset_index()

相关问题 更多 >