2015-06-11 4 views
0

У меня есть панд dataframe в следующем виде:Повышение конверсии dataframe панд в Python

  id2_cond1 id2_cond2 id2_cond3 id2_cond4 
id2_cond1 1.000000 0.819689 -0.753702 -0.617213 
id2_cond2 0.819689 1.000000 -0.554437 -0.295122 
id2_cond3 -0.753702 -0.554437 1.000000 0.939336 
id2_cond4 -0.617213 -0.295122 0.939336 1.000000 

То, что я хочу сделать, это преобразовать dataframe в следующем виде:

 cond1_cond2 cond1_cond3 cond1_cond4 cond2_cond3 cond2_cond4 cond3_cond4 
id2 0.8196886 -0.7537023 -0.6172134 -0.554437 -0.2951216 0.9393364 

I может сделать это правильно, используя следующий сценарий:

df_tmp = pd.DataFrame(index=[identifier], columns=cols) 
counter = 0 
for x in range(len(df)): 
    for y in range(x + 1, len(df)): 
     df_tmp.ix[0, counter] = df.ix[x, y] 
     counter += 1 
print(df_tmp) 

Проблема с этим подходом заключается в том, что я должен предварительно определить e столбцы, и я должен знать порядок.

cols = ["cond1_cond2", "cond1_cond3", "cond1_cond4", "cond2_cond3", "cond2_cond4", "cond3_cond4"] 

Есть ли лучший способ преобразования этого блока данных, который автоматически создает различные комбинации?

+1

От где вы получите оригинальный dataframe? Он выглядит как продукт двух исходных данных. Я чувствую, что, хотя это тривиальная проблема для решения, но я думаю, что вы, возможно, пытаетесь решить проблему более сложным образом, чем это необходимо. – firelynx

+0

Первоначально у меня есть кортеж в следующей форме: (('id2_cond1', [0, 1, 2, 3, 4, 5]), ('id2_cond2', [3, 1, 3, 3, 4, 5]), ('id2_cond3', [9, 1, 2, 3, 0, 0]), ('id2_cond4', [12, 1, 3, 3, 1, 1])). Я преобразую его в dict, а затем в фрейм данных, чтобы вычислить коэффициент коэрбитации: df = pd.DataFrame (dict (f)). Corr (method = 'spearman') – fitziano

+1

Может быть, этот вопрос будет связан с тем, что вы хотите? http://stackoverflow.com/questions/24002820/returning-groups-of-correlated-columns-in-pandas-data-frame – firelynx

ответ

1

Оригинал DataFrame:

df = pd.DataFrame({'id2_cond1': {'id2_cond1': 1.0, 'id2_cond2': 0.81968899999999989, 'id2_cond3': -0.75370200000000009, 'id2_cond4': -0.61721300000000001}, 
        'id2_cond2': {'id2_cond1': 0.81968899999999989, 'id2_cond2': 1.0, 'id2_cond3': -0.55443699999999996, 'id2_cond4': -0.295122}, 
        'id2_cond3': {'id2_cond1': -0.75370200000000009, 'id2_cond2': -0.55443699999999996, 'id2_cond3': 1.0, 'id2_cond4': 0.93933600000000006}, 
        'id2_cond4': {'id2_cond1': -0.61721300000000001, 'id2_cond2': -0.295122, 'id2_cond3': 0.93933600000000006, 'id2_cond4': 1.0}}) 

Во-первых, давайте вырезать имя ('id2' в данном примере):

name = df.index[0].split("_")[0] 

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

conds = ["_".join(i.split("_")[1:]) for i in df.index] 

Теперь, давайте использовать список понимание для генерации всех комбинаций имен:

idx = ['{0}_{1}'.format(conds[i], conds[j]) 
     for i in range(len(conds)) 
     for j in range(i + 1, len(conds))] 

Мы будем использовать ту же технику, чтобы сгладить данные:

data = [df.iat[i, j] 
     for i in range(len(conds)) 
     for j in range(i + 1, len(conds))] 

Наконец, мы создадим серию из приведенной выше информации:

corr_matrix_flat = pd.Series(data, index=idx, name=name) 
>>> corr_matrix 
cond1_cond2 0.819689 
cond1_cond3 -0.753702 
cond1_cond4 -0.617213 
cond2_cond3 -0.554437 
cond2_cond4 -0.295122 
cond3_cond4 0.939336 
Name: id2, dtype: float64 
0

Вот еще одна версии, использующей pandas встроенной функции stack.

import pandas as pd 

df = pd.DataFrame({'id2_cond1': {'id2_cond1': 1.0, 'id2_cond2': 0.81968899999999989, 'id2_cond3': -0.75370200000000009, 'id2_cond4': -0.61721300000000001}, 
        'id2_cond2': {'id2_cond1': 0.81968899999999989, 'id2_cond2': 1.0, 'id2_cond3': -0.55443699999999996, 'id2_cond4': -0.295122}, 
        'id2_cond3': {'id2_cond1': -0.75370200000000009, 'id2_cond2': -0.55443699999999996, 'id2_cond3': 1.0, 'id2_cond4': 0.93933600000000006}, 
        'id2_cond4': {'id2_cond1': -0.61721300000000001, 'id2_cond2': -0.295122, 'id2_cond3': 0.93933600000000006, 'id2_cond4': 1.0}}) 

Преобразовать df в Series по df.stack()

s = df.stack() 
print s 

Выход

id2_cond1 id2_cond1 1.000000 
      id2_cond2 0.819689 
      id2_cond3 -0.753702 
      id2_cond4 -0.617213 
id2_cond2 id2_cond1 0.819689 
      id2_cond2 1.000000 
      id2_cond3 -0.554437 
      id2_cond4 -0.295122 
id2_cond3 id2_cond1 -0.753702 
      id2_cond2 -0.554437 
      id2_cond3 1.000000 
      id2_cond4 0.939336 
id2_cond4 id2_cond1 -0.617213 
      id2_cond2 -0.295122 
      id2_cond3 0.939336 
      id2_cond4 1.000000 
dtype: float64 

Следующая удалить диагональные и нижние части треугольника.

ind_upper = [] 
    for i in range(len(df)): 
     for j in range(len(df)): 
...   if i < j: 
...    ind_upper.append(True) 
...   else: 
...    ind_upper.append(False) 

s = s[ind_upper] 

Следующий индекс комбинирования и столбцы в одном.

index = list(s.index) 
print index 
[('id2_cond1', 'id2_cond2'), ('id2_cond1', 'id2_cond3'), ('id2_cond1', 'id2_cond4'), ('id2_cond2', 'id2_cond3'), ('id2_cond2', 'id2_cond4'), ('id2_cond3', 'id2_cond4')] 

index = ['_'.join(id) for id in index] 
index = [id.replace('id2_', '') for id in index] 
print index 
['cond1_cond2', 'cond1_cond3', 'cond1_cond4', 'cond2_cond3', 'cond2_cond4', 'cond3_cond4'] 

Присвоить index к s

s.index = index 
print s 
cond1_cond2 0.819689 
cond1_cond3 -0.753702 
cond1_cond4 -0.617213 
cond2_cond3 -0.554437 
cond2_cond4 -0.295122 
cond3_cond4 0.939336 
dtype: float64 
+0

Одной из проблем с этим решением является то, что он сообщает больше о комбинации, чем следовало бы. Например, в нем содержатся как cond1_cond_2, так и cond2_cond1 – fitziano

+0

Проблема решена. Удалены диагональные и нижние треугольные части df. – dct

Смежные вопросы