Создайте df с простой комбинацией из group по существующему фрейму данных в pandas

#python #pandas #dataframe #group-by #combinations

#python #pandas #фрейм данных #группировка по #комбинации

Вопрос:

Я пытаюсь создать pandas df , пересекающие строки по паре. Я объясню лучше:

на мой df взгляд, есть несколько групп, которые имеют два значения для каждой строки, так что df это сборка, подобная:

 Group Car Value
  A    x    0.1
  A    y    0.5
  A    z    0.12
  B    x    1.1
  B    w    1.26
  B    y    0.7
  

Что я пытаюсь сделать, так это создать новый df , в котором каждый автомобиль, принадлежащий группе, находится в том же ряду, что и другой автомобиль в той же группе, для всех возможных комбинаций внутри группы (в виде простой комбинации).

Примечание: автомобили имеют разные значения в разных группах.

То df , что я хотел бы, это:

 Car1 Car2 Value1 Value2
 x    y     0.1    0.5
 x    z     0.1    0.12
 y    z     0.5    0.12
 x    w     1.1    1.26
 x    y     1.1    0.7
 w    y     1.26   0.7
  

Я пытался использовать что-то вроде:

  pd.DataFrame([[np.hstack([g.car[prev],g.car[cur],g.value[prev],g.value[cur]]) 
                for _,g in df.groupby(['group'])] 
                for prev, cur in zip(g.index, g.index[1:])],
                columns=['car1','car2','value1','value2']
              )
  

но это не решает мою проблему.

Спросите меня, если мой вопрос неясен.

Комментарии:

1. Это может быть полезно geeksforgeeks.org/permutation-and-combination-in-python

Ответ №1:

groupby df Group Затем для каждого сгруппированного фрейма сопоставьте столбец on с функцией f , которая вычисляет всю combinations длину 2 автомобилей в этой группе:

 from itertools import combinations

def f(g):
    for c in combinations(g.index, r=2):
        yield np.hstack(g.loc[c, ['Car', 'Value']].T.values)

a = np.vstack([*f(g)] for _, g in df.groupby('Group'))
d = pd.DataFrame(a, columns=['Car1', 'Car2', 'Value1', 'Value2'])
  

   Car1 Car2 Value1 Value2
0    x    y    0.1    0.5
1    x    z    0.1   0.12
2    y    z    0.5   0.12
3    x    w    1.1   1.26
4    x    y    1.1    0.7
5    w    y   1.26    0.7
  

Ответ №2:

Вы используете самосоединение и фильтруете результаты:

 dfn=df.assign(row=df.groupby('Group').cumcount())

dfn.merge(dfn, on=['Group'], suffixes=('1','2')).query('row1 < row2').drop(['row1','row2'], axis=1)
  

Вывод:

    Group Car1  Value1 Car2  Value2
1      A    x    0.10    y    0.50
2      A    x    0.10    z    0.12
5      A    y    0.50    z    0.12
10     B    x    1.10    w    1.26
11     B    x    1.10    y    0.70
14     B    w    1.26    y    0.70
  

Комментарии:

1. Не тогда, когда входной набор данных очень большой, он будет генерировать массу дополнительных записей.