Создание формата матрицы из python

#python #pandas #numpy #matrix #crosstab

#python #pandas #numpy #матрица #перекрестная таблица

Вопрос:

У меня есть следующие данные в моем фрейме данных B:

 F1     F2    Count
A      C      5
B      C      2
B      U      6
C      A      1
  

Я хочу сделать из них квадратную матрицу, чтобы результаты были:

     A    B   C  U
A   0    0   6  0
B   0    0   2  6
C   6    2   0  0
U   0    6   0  0
  

Изначально я использовал pd.crosstab() , но в матрице отсутствуют некоторые переменные в F1 / F2.

AC = 5 CA = 1, поэтому результат должен быть 6.

Также pdcrosstab() не распознает BU = UB и т. Д.

Кто-нибудь, кто мог бы помочь? Я в основном новичок в python.

Кстати, это мой код:

 wow=pd.crosstab(B.F1, 
            B.F2, 
            values=B.Count, 
            aggfunc='sum',
            ).rename_axis(None).rename_axis(None, axis=1)
  

Ответ №1:

Вы можете pd.concat , wow а wow.T затем groupby индексировать и sum снова:

 >>> wow=pd.crosstab(B.F1, 
            B.F2, 
            values=B.Count, 
            aggfunc='sum',
            ).rename_axis(None).rename_axis(None, axis=1)
>>> wow
     A    C    U
A  NaN  5.0  NaN
B  NaN  2.0  6.0
C  1.0  NaN  NaN

>>> pd.concat([wow, wow.T], sort=True).fillna(0, downcast='infer').groupby(level=0).sum()
   A  B  C  U
A  0  0  6  0
B  0  0  2  6
C  6  2  0  0
U  0  6  0  0
  

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

1. Добавление этой последней строки в мой исходный код сработало! Спасибо!

Ответ №2:

Вы можете сделать столбцы F1 и F2 категориальными и использовать crosstab для работы.

 FDtype = pd.CategoricalDtype(list("ABCU"))

df[["F1", "F2"]] = df[["F1", "F2"]].astype(FDtype)
count = pd.crosstab(df["F1"], df["F2"], df["Count"], aggfunc='sum', dropna=False)
count.fillna(0, inplace=True, downcast="infer")
count  = count.T
  

Замечание: более эффективно указывать dtypes столбцов при создании фрейма данных

Ответ №3:

Вы можете добавить фрейм данных, где 'F1' и 'F2' заменяются на исходный фрейм данных.

 df1 = df.append(df.rename({'F1': 'F2', 'F2': 'F1'}, axis=1), sort=False)
  

Затем вы можете использовать pivot_table :

 pd.pivot_table(df1, values='Count', index='F1', columns='F2', aggfunc='sum', fill_value=0)
  

или crosstab :

 pd.crosstab(df1.F1, df1.F2, df1.Count, aggfunc='sum').fillna(0)
  

Наконец, удалите столбцы и имена индексов:

 del df1.columns.name, df1.index.name
  

Результат:

    A  B  C  U
A  0  0  6  0
B  0  0  2  6
C  6  2  0  0
U  0  6  0  0