多列的itertools组合

Itertools combinations of multiple columns

我有这个数据

product color size
p1      Red   XXL
p2      Blue  XL
p3            L
              S

我想按如下方式对各列进行组合:

p1, Red, XXL
p1, Red, XL
.
.
p3, Blue, S

我尝试将所有列都放在一个列表中然后使用 itertools.combinations 但结果包含一些不需要的数据,例如:

p1, p2, p3
OR
Red, Blue, XXL
OR
XXL, XL, S ....

我的代码是:

df = read_csv('./GenerateProducts.csv', delimiter=',')
df_columns = df.columns.tolist()
list_data = DataFrame()
for i in df_columns:
    list_data = concat([list_data,df[i].dropna(axis=0)])
generated_products = DataFrame( combinations( list_data[0] ,len(df_columns) ) )

我也在努力让它变得动态 我试着把列变成字典,然后使用键作为数据的指针,但我不知道如何实现这个逻辑,我对字典的经验太浅了

data = dict()
for i in df_columns:
    data[i] = df[i].dropna(axis=0)

我读了一篇关于 itertools.product 的文章,这就是为什么我让 dict 也使用 for 循环来使用 dict 键进行相同的更改。

我认为我对 dict 的执行让我感到困惑,任何指导

编辑:

我成功了

temp = []
for i in df_columns:
    temp += [data[i]]
    
final_df = DataFrame(product(*temp), columns=df_columns)
final_df

我想知道是否有更有效的方法来实现相同的结果

谢谢

是的,有一个更有效的方法,使用 itertools.product():

import itertools

prod1 = ['p1', 'p2', 'p3']
color1 = ['Red', 'Blue']
size1 = ['XXL', 'XL', 'L', 'S']
t1 = itertools.product(prod1, color1, size1)
for t in t1:
    print(t)

输出

('p1', 'Red', 'XXL')
('p1', 'Red', 'XL')
('p1', 'Red', 'L')
('p1', 'Red', 'S')
('p1', 'Blue', 'XXL')
('p1', 'Blue', 'XL')
('p1', 'Blue', 'L')
('p1', 'Blue', 'S')
('p2', 'Red', 'XXL')
('p2', 'Red', 'XL')
('p2', 'Red', 'L')
('p2', 'Red', 'S')
('p2', 'Blue', 'XXL')
('p2', 'Blue', 'XL')
('p2', 'Blue', 'L')
('p2', 'Blue', 'S')
('p3', 'Red', 'XXL')
('p3', 'Red', 'XL')
('p3', 'Red', 'L')
('p3', 'Red', 'S')
('p3', 'Blue', 'XXL')
('p3', 'Blue', 'XL')
('p3', 'Blue', 'L')
('p3', 'Blue', 'S')

我假设您的数据在数据框中的存储方式如下(5 行 x 3 列)。

  product color size
0      p1   Red  XXL
1      p2  Blue   XL
2      p3          L
3                  S

使用列表理解

你想创建一个包含这些的组合的数据框。您可以使用列表理解来执行此操作,然后根据结果创建数据框。

操作方法如下。

import pandas as pd
df = pd.DataFrame({'product':['p1','p2','p3',''],
                   'color':['Red','Blue','',''],
                   'size':['XXL','XL','L','S']})

outlist = [(i,j,k)
           for i in df['product'] if i != ''
           for j in df['color'] if j != ''
           for k in df['size']]

newdf = pd.DataFrame(data=outlist,columns=['product','color','size'])
print (newdf)

新数据框将是:

   product color size
0       p1   Red  XXL
1       p1   Red   XL
2       p1   Red    L
3       p1   Red    S
4       p1  Blue  XXL
5       p1  Blue   XL
6       p1  Blue    L
7       p1  Blue    S
8       p2   Red  XXL
9       p2   Red   XL
10      p2   Red    L
11      p2   Red    S
12      p2  Blue  XXL
13      p2  Blue   XL
14      p2  Blue    L
15      p2  Blue    S
16      p3   Red  XXL
17      p3   Red   XL
18      p3   Red    L
19      p3   Red    S
20      p3  Blue  XXL
21      p3  Blue   XL
22      p3  Blue    L
23      p3  Blue    S

使用 itertools 的产品

替代方法是使用 itertools

中的 product

您可以这样做:

import pandas as pd
from itertools import product
df = pd.DataFrame({'product':['p1','p2','p3',''],
                   'color':['Red','Blue','',''],
                   'size':['XXL','XL','L','S']})

print (df)

new_df = pd.DataFrame(data=list(product(df['product'],
                                        df['color'],
                                        df['size'])),
                      columns=['product','color','size'])
new_df.drop(new_df[(new_df['product'] == '') | (new_df['color'] == '')].index, inplace = True)
new_df = new_df.reset_index(drop=True)
print (new_df)

请注意,我必须删除具有 product = ''size = '' 的行,因为数据框具有这些值,我们想忽略它们。

结果将是:

   product color size
0       p1   Red  XXL
1       p1   Red   XL
2       p1   Red    L
3       p1   Red    S
4       p1  Blue  XXL
5       p1  Blue   XL
6       p1  Blue    L
7       p1  Blue    S
8       p2   Red  XXL
9       p2   Red   XL
10      p2   Red    L
11      p2   Red    S
12      p2  Blue  XXL
13      p2  Blue   XL
14      p2  Blue    L
15      p2  Blue    S
16      p3   Red  XXL
17      p3   Red   XL
18      p3   Red    L
19      p3   Red    S
20      p3  Blue  XXL
21      p3  Blue   XL
22      p3  Blue    L
23      p3  Blue    S