将对列表转换为最小可能的 DataFrame 表示?

Rob*_*ose -1 python numpy linear-algebra pandas

我有一个配对项目列表,我想将它们转换成一个 Pandas DataFrame,其中每个配对项目在同一列中共享相同的数字。所以像这样:

[('A', 'B'),
('A', 'C'),
('B', 'D')]
Run Code Online (Sandbox Code Playgroud)

转化为...

  0  1
A 2  1
B 3  1
C 2  0
D 3  0
Run Code Online (Sandbox Code Playgroud)

因此,列按编码对的数量降序排列,并且它使用尽可能少的列。

是否有一种算法,最好是 numpy 或 Pandas 中的某种算法,可以做到这一点?到目前为止,我在谷歌上找不到任何东西,但我已经有一段时间没有使用线性代数了,所以我可能只是忘记了正确的使用术语。

我创建了以下(有问题的)代码来创建一个 DataFrame,但由于某种原因,它创建了与对一样多的列,这不是我想要完成的。

def create_df(ps):
    df = pd.DataFrame(index=np.unique(ps))
    cnt = 1
    for p in ps:
        col = 0
        a, b = p
        while col in df.columns and (df.at[a, col] != 0 or df.at[b, col] != 0):
            col += 1
        df.loc[a, col] = cnt
        df.loc[b, col] = cnt
        cnt += 1
    return df
Run Code Online (Sandbox Code Playgroud)

这样做的最终目标是将输出集成到数据管道中,以便我可以在 Pandas 中使用 groupby 来计算对的统计数据。因此,每一对都必须在同一列中定义,如示例中所示。

WeN*_*Ben 5

这更像是pivot我们做后的问题melt

s=pd.DataFrame(l).reset_index().melt('index')
s=s.assign(Col=s.groupby('value').cumcount()).pivot('value','Col','index').\
    add(1).fillna(0)
s
Out[62]: 
Col      0    1
value          
A      1.0  2.0
B      3.0  1.0
C      2.0  0.0
D      3.0  0.0
Run Code Online (Sandbox Code Playgroud)