如何找出Dataframe中两列的组合?当数据框中有多列时?

问题描述

我有以下数据框...

df1:
playerA   playerB  PlayerC PlayerD
kim         lee      b      f
jackson     kim      d      g
dan         lee      a      d

我想生成一个包含两列所有可能组合的新数据框。例如,

df_new:
Target   Source  
kim         lee
kim         kim
kim         lee
kim          b     
kim          d
kim          a
kim          f
kim          g
kim          d      
jackson      lee
jackson      kim
jackson      lee
jackson      b
.
.
.
.
lee         kim
lee         jackson
lee          dan
lee          b
lee          d
.
.
.

因此,我尝试了此代码 t

import itertools
def comb(df1):
    return [df1.loc[:,list(x)].set_axis(['Target','Source'],axis=1)
            for x in itertools.combinations(df1.columns,2)]

但是,它只显示同一行中列之间的组合。

有什么办法可以在列之间生成所有可能的组合?提前致谢!

解决方法

itertools经过permutationsproductchain.from_iterable的一种方式:

from itertools import chain,permutations,product

df = pd.DataFrame(
         chain.from_iterable(product(df1[col_1],df1[col_2])
                             for col_1,col_2 in permutations(df1.columns,r=2)),columns=["Target","Source"]
)

我们首先得到所有列的 2-{{​​1}},然后对于每一对,形成它们的值的 permutations。对所有排列执行此操作后,使用 product 将它们展平并传递给数据帧构造函数。

我得到一个 108 x 2 的数据帧:

chain.from_iterable

(其中 108 = 3*9*4:3 = 行,9 = 行 * 其他列,4 = 总列)。

,

这是使用 pandas.DataFrame.melt()pandas.merge()

的方法
>>> df1
   playerA playerB PlayerC PlayerD
0      kim     lee       b       f
1  jackson     kim       d       g
2      dan     lee       a       d
>>> target = df1.melt(value_name='Source')[['Source']]
>>> df_new = pd.merge(target.rename(columns={'Source':'Target'}),target,how='cross')
>>> df_new
    Target   Source
0      kim      kim
1      kim  jackson
2      kim      dan
3      kim      lee
4      kim      kim
..     ...      ...
139      d        d
140      d        a
141      d        f
142      d        g
143      d        d

这种方法不考虑 TargetSource 的相同索引,但您可以使用简单的数学方法轻松删除这些行,如下所示:

>>> indices_to_drop = [idx * len(target) + idx for idx in range(len(target)]
>>> indices_to_drop
[0,13,26,39,52,65,78,91,104,117,130,143]
>>> df_new.drop(indices_to_drop).reset_index(drop=True)
    Target   Source
0      kim  jackson
1      kim      dan
2      kim      lee
3      kim      kim
4      kim      lee
..     ...      ...
127      d        b
128      d        d
129      d        a
130      d        f
131      d        g
,

您可以使用列表理解。

df = pd.DataFrame(columns=["Target","Source"])
for col in df1:
    df = pd.concat(
        [
            df,pd.DataFrame(
                [
                    {"Target": val1,"Source": val2}
                    for val2 in df1.loc[:,df1.columns.difference([col])].values.flatten()
                    for val1 in df1[col]
                ]
            ),],)

df
    Target  Source
0   kim b
1   jackson b
2   dan b
3   kim f
4   jackson f
... ... ...
22  g   dan
23  d   dan
24  f   lee
25  g   lee
26  d   lee
108 rows × 2 columns

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...