Python 如何找出Dataframe中两列的组合?当数据帧中有多列时?
我有以下数据帧Python 如何找出Dataframe中两列的组合?当数据帧中有多列时?,python,pandas,itertools,Python,Pandas,Itertools,我有以下数据帧 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
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
到via的路径,以及:
我们首先得到所有列的2-排列
,然后对于每一对,形成其值的乘积。对所有排列执行此操作后,使用chain.from_iterable
将它们展平,并传递给数据帧构造函数
我得到一个108 x 2的数据帧:
Target Source
0 kim lee
1 kim kim
2 kim lee
3 jackson lee
4 jackson kim
.. ... ...
103 g d
104 g a
105 d b
106 d d
107 d a
(其中108=3*9*4:3=行,9=行*其他列,4=总列)。以下是使用and的方法
此方法不考虑相同的索引>代码>目标< /代码>和<代码>源>代码>,但您可以使用以下简单的数学方法轻松地删除这些行:
>>> 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(列=[“目标”,“源”])
对于df1中的col:
df=pd.concat(
[
df,
数据帧(
[
{“Target”:val1,“Source”:val2}
对于df1.loc[:,df1.columns.difference([col])].values.flatte()中的val2
对于df1中的val1[col]
]
),
],
)
df
我认为行的数量太多了(144>108)。在删除这些索引之前,这个解决方案本身也需要一个列的乘积,我认为这很有用,但可能不是OP想要的。然而,在降低这些指数之后,它介于两者之间。这真的很好。我能再问一个问题吗?什么是“链”?“对于列1,排列中的列2(df1.columns,r=2)”意味着@DAEHYUNKIMchain
用于展平列表,您可以看到这一点。在这种情况下,例如像[(“kim”、“lee”),(“kim”、“kim”),[(“jackson”、“lee”),(“jackson”、“kim”)]
这样的列表中有两个列表。在chain
之后,它变成了[(“kim”,“lee”),(“kim”,“kim”),(“jackson”,“lee”),(“jackson”,“kim”)]
(注意里面消失的[,]
,它现在是一个4项的单一列表)。@DAEHYUNKIM对于排列
,它采用列的名称并生成2个排列。它给出了[('playerA','playerB'),('playerA','PlayerC'),('playerA','PlayerD'),('playerB','PlayerC'),('PlayerC','playerB'),('PlayerC','PlayerD'),('PlayerD','PlayerD','PlayerD'),('PlayerD','PlayerD','PlayerD'),('PlayerD','PlayerD'),('PlayerD','PlayerD'),('PlayerD','PlayerC')
。然后用为col\u 1,col\u 2
,我们将循环为循环,并且col\u 1
和col\u 2
在每个循环中分配给这些对。哎,这对我帮助很大。谢谢
>>> 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
>>> 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
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