Получить комбинации из нескольких столбцов (декартово произведение) кадра данных панд? - PullRequest
0 голосов
/ 02 сентября 2018

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

             Steve     John      
    Model1   0.327586  0.289474 
    Model2   0.322581  0.285714 
    Model3   0.303030  0.294118

Мне нужен кадр данных, представляющий все комбинации значений модели по столбцам, т. Е. Декартово произведение всех столбцов . Таким образом, вышеприведенное будет преобразовано в следующее.

             model Steve     value Steve    model John     value John     
    0        Model1          0.327586       Model1         0.289474
    1        Model1          0.327586       Model2         0.285714
    2        Model1          0.327586       Model3         0.294118
    3        Model2          0.322581       Model1         0.289474
    4        Model2          0.322581       Model2         0.285714
    5        Model2          0.322581       Model3         0.294118
    6        Model3          0.303030       Model1         0.289474
    7        Model3          0.303030       Model2         0.285714
    8        Model3          0.303030       Model3         0.294118

Выше приведен простой случай, но теоретически я хотел бы иметь возможность сделать это для N моделей и M кандидатов, в результате чего получается кадр данных с N ^ M строками и 2M столбцами (на практике N <20, M < 6). </p>

При поиске ответа я видел много рекомендаций для модуля itertools для подобных вещей, но не мог понять, как получить все комбинации в нескольких списках (itertools.combinations, кажется, только работать над поиском всех комбинаций в одном списке).

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Всегда лучше предоставить код, чтобы мы могли быстро создать фрейм, а не просто таблицу. В любом случае вы можете создать общий key и создать базу данных, например, перекрестное соединение, чтобы получить конечный результат. Вы можете сделать это в одну строку, но я делаю шаг за шагом.

import pandas as pd


df = pd.DataFrame({'model': ['model1', 'model2'],
                   'steve': ['a', 'b'],
                   'jhon': ['c', 'd']
                  })

# create a common key

df['key'] = 'xyz'

# create two seperate dataframe for self join
# but it is possible to use the direct operation (right side) in 
# inside of merge funciton

df_steve = df [['model', 'steve', 'key']]
df_jhon = df [['model', 'jhon', 'key']]

# self join    
pd.merge(df_steve, df_jhon, on='key', suffixes=('_steve', '_jhon')).drop('key', axis=1)

Выход:

  model_steve steve model_jhon jhon
0      model1     a     model1    c
1      model1     a     model2    d
2      model2     b     model1    c
3      model2     b     model2    d

Код одного вкладыша:

cross_df = pd.merge(df[['model', 'steve', 'key']], 
                    df[['model', 'jhon', 'key']], 
                    on='key', 
                    suffixes=('_steve', '_jhon')
                    ).drop('key', axis=1)

просто измените имя столбца в соответствии с вашими потребностями.

0 голосов
/ 02 сентября 2018

Использование:

from  itertools import product

#get all combinations of all columns
a = product(*[zip(df.index, x) for x in df.T.values])
#create new columns names
cols = [c for x in df.columns for c in ('model_' + x, 'value_' + x)]
#flattening nested lists with DataFrame contructor
df1 = pd.DataFrame([[y for x in z for y in x] for z in a], columns=cols)
print (df1)
  model_Steve  value_Steve model_John  value_John
0      Model1     0.327586     Model1    0.289474
1      Model1     0.327586     Model2    0.285714
2      Model1     0.327586     Model3    0.294118
3      Model2     0.322581     Model1    0.289474
4      Model2     0.322581     Model2    0.285714
5      Model2     0.322581     Model3    0.294118
6      Model3     0.303030     Model1    0.289474
7      Model3     0.303030     Model2    0.285714
8      Model3     0.303030     Model3    0.294118
...