Кадр данных в матрицу nxn - PullRequest
       3

Кадр данных в матрицу nxn

0 голосов
/ 07 января 2020

У меня очень большой фрейм данных, пример которого выглядит следующим образом:

df = pd.DataFrame({'From':['a','b','c','a','d'], 'To':['b', 'c', 'a', 'd', 'e'], 'Rates':[1e-4, 2.3e-2, 1e-2, 100, 70]})

In[121]: df
Out[121]: 
  From To     Rates
0    a  b    0.0001
1    b  c    0.0230
2    c  a    0.0100
3    a  d  100.0000
4    d  e   70.0000

Конечный результат, который я хотел бы получить, - n x n матрица model_matrix (где n = len(df)) это выглядит следующим образом:

      a       b      c      d     e
a  0.00  0.0001  0.000  100.0   0.0
b  0.00  0.0000  0.023    0.0   0.0
c  0.01  0.0000  0.000    0.0   0.0
d  0.00  0.0000  0.000    0.0  70.0
e  0.00  0.0000  0.000    0.0   0.0

Следующий код работает путем преобразования df в словарь transfer_rates и заполнения model_matrix значениями из словаря, но это очень неэффективно для большой df.

from_comps = list(df['From'])
to_comps = list(df['To'])
transfer_rates = {}
for from_comp in from_comps:
    for to_comp in to_comps:
        try:
            transfer_rates[from_comp, to_comp] = df.loc[(df['From'] == from_comp) & (df['To'] == to_comp)]['Rates'].values[0]
        except:
            pass

all_comps = sorted(set(from_comps+to_comps))

model_matrix = pd.DataFrame(columns=sorted(all_comps),index=sorted(all_comps))
for rate in transfer_rates:
    model_matrix[rate[1]][rate[0]] = transfer_rates[rate]
model_matrix.fillna(0, inplace=True)

Есть ли более эффективный способ сделать это?

Ответы [ 3 ]

1 голос
/ 07 января 2020

Это работает:

In [85]: df2 = df.pivot(index="From", columns="To", values="Rates")                                                                                                                                                

In [86]: full_index = df2.index.union(df2.columns)                                                                                                                                                                 

In [87]: df2 = df2.reindex(labels=full_index, axis=0).reindex(labels=full_index, axis=1).fillna(0.0)                                                                                                               

In [88]: df2                                                                                                                                                                                                       
Out[88]: 
      a       b      c      d     e
a  0.00  0.0001  0.000  100.0   0.0
b  0.00  0.0000  0.023    0.0   0.0
c  0.01  0.0000  0.000    0.0   0.0
d  0.00  0.0000  0.000    0.0  70.0
e  0.00  0.0000  0.000    0.0   0.0

Адаптировано из этого вопроса: Как сделать прямоугольник angular квадрат матрицы на pandas фрейм данных

1 голос
/ 07 января 2020

Вы можете использовать pandas.pivot():

>>> df2 = df.pivot(index="From", columns="To", values="Rates")
>>> allopts=list("abcdefgh") #Define all possible options
>>> df3=pd.DataFrame(index=allopts, columns=allopts) #Create empty df to cover for empty rows/cols
>>> df4=pd.concat([df2,df3], sort=False)
>>> df4.groupby(df4.index).first().fillna(0)
      a       b      c      d     e    f    g    h
a  0.00  0.0001  0.000  100.0   0.0  0.0  0.0  0.0
b  0.00  0.0000  0.023    0.0   0.0  0.0  0.0  0.0
c  0.01  0.0000  0.000    0.0   0.0  0.0  0.0  0.0
d  0.00  0.0000  0.000    0.0  70.0  0.0  0.0  0.0
e  0.00  0.0000  0.000    0.0   0.0  0.0  0.0  0.0
f  0.00  0.0000  0.000    0.0   0.0  0.0  0.0  0.0
g  0.00  0.0000  0.000    0.0   0.0  0.0  0.0  0.0
h  0.00  0.0000  0.000    0.0   0.0  0.0  0.0  0.0

Ссылка:

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.pivot.html

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html

0 голосов
/ 07 января 2020

Используйте set_index, unstack и align

df1 = df.set_index(['From','To']).Rates.unstack(fill_value=0)
df_final = df1.align(df1.T, fill_value=0)[0]

Out[586]:
      a       b      c      d     e
a  0.00  0.0001  0.000  100.0   0.0
b  0.00  0.0000  0.023    0.0   0.0
c  0.01  0.0000  0.000    0.0   0.0
d  0.00  0.0000  0.000    0.0  70.0
e  0.00  0.0000  0.000    0.0   0.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...