亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在Python中從字典中獲取對稱矩陣

如何在Python中從字典中獲取對稱矩陣

牧羊人nacy 2023-07-05 17:59:18
我有一個關于 Python 中數據操作的基本問題。我有以下字典:mydict={('A', 'E'): 23972, ('A', 'D'): 10730, ('A', 'B'): 14748, ('A', 'C'): 3424, ('E', 'D'): 3294, ('E', 'B'): 16016, ('E', 'C'): 3373, ('D', 'B'): 69734, ('D', 'C'): 4662, ('B', 'C'): 159161}如果仔細觀察,這是一個對角線為零的對稱矩陣的一半(不包括 0)。我的最終目標是編寫一個具有完整矩陣的 pandas 數據框。暫定方案我考慮過“解壓”字典,獲取 5 個列表,每個標簽一個,所有值都與其他標簽相關,在列表的自身位置添加 0。對于標簽“A”和“B”,所需的結果是:A=[0,mydict(['A','B']),mydict(['A','C']),mydict(['A','D']),mydict(['A','E'])]B=[mydict(['A','B']),0,mydict(['B','C']),mydict(['D','B']),mydict(['E','B'])]C、D、E 依此類推。請注意,在 B 中,第 4 個和第 5 個元素是 mydict(['D','B']) 和 mydict(['E','B']),因為 mydict(['B','D']) mydict(['B','E']) 根本不存在于 mydict 中。這樣我就可以輕松地從這些列表中填充數據框:import pandas as pddf=pd.DataFrame(columns=['A','B','C','D','E'])df['A']=Adf['B']=B問題我不太確定如何將 mydict“解壓”到這些列表中,或解壓到任何其他可以幫助我構建矩陣的容器中。有什么建議么?
查看完整描述

4 回答

?
蠱毒傳說

TA貢獻1895條經驗 獲得超3個贊

一種選擇是以完整矩陣格式重建字典,然后用 pandas 對其進行旋轉:


import pandas as pd

mydict={('A', 'E'): 23972,

?('A', 'D'): 10730,

?('A', 'B'): 14748,

?('A', 'C'): 3424,

?('E', 'D'): 3294,

?('E', 'B'): 16016,

?('E', 'C'): 3373,

?('D', 'B'): 69734,

?('D', 'C'): 4662,

?('B', 'C'): 159161}

?

?

# construct the full dictionary

newdict = {}


for (k1, k2), v in mydict.items():

? ? newdict[k1, k2] = v

? ? newdict[k2, k1] = v

? ? newdict[k1, k1] = 0

? ? newdict[k2, k2] = 0


# pivot the result from long to wide

pd.Series(newdict).reset_index().pivot(index='level_0', columns='level_1', values=0)


#level_1? ? ? A? ? ? ?B? ? ? ?C? ? ? D? ? ? E

#level_0? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

#A? ? ? ? ? ? 0? ?14748? ? 3424? 10730? 23972

#B? ? ? ? 14748? ? ? ?0? 159161? 69734? 16016

#C? ? ? ? ?3424? 159161? ? ? ?0? ?4662? ?3373

#D? ? ? ? 10730? ?69734? ? 4662? ? ? 0? ?3294

#E? ? ? ? 23972? ?16016? ? 3373? ?3294? ? ? 0


查看完整回答
反對 回復 2023-07-05
?
慕勒3428872

TA貢獻1848條經驗 獲得超6個贊

這是一個直接的解決方案,運行起來也不應該花費太多時間 -


cols = np.unique(list(mydict.keys())).ravel()


df = pd.DataFrame(0, columns=cols, index=cols)


for i in mydict.items():

    df.loc[i[0]] = i[1] 


df = df + df.T

print(df)

       A       B       C      D      E

A      0   14748    3424  10730  23972

B  14748       0  159161  69734  16016

C   3424  159161       0   4662   3373

D  10730   69734    4662      0   3294

E  23972   16016    3373   3294      0

基準測試


添加基準(303長度輸入,MacBook pro 13)-


kk = 'ABCDEFGHIJKLMNOPQURSUVWXYZ'

mydict = {i:np.random.randint(1,10000) for i in itertools.combinations(kk,2)}

len(mydict)

#303

  • fusion 的方法- 每個循環 392 μs ± 16.4 μs(7 次運行的平均值 ± 標準差,每次 1000 個循環)

  • Psidom 的方法- 每個循環 4.95 ms ± 286 μs(7 次運行的平均值 ± 標準差,每次 100 個循環)

  • Akshay Sehgal 的方法- 每個循環 34.8 ms ± 884 μs(7 次運行的平均值 ± 標準差,每次 10 個循環)

  • Ben.T 的方法- 每個循環 4.01 ms ± 282 μs(7 次運行的平均值 ± 標準差,每次 100 個循環)

Fusion 的方法是最快的。


查看完整回答
反對 回復 2023-07-05
?
有只小跳蛙

TA貢獻1824條經驗 獲得超8個贊

我能想到的是首先將字典值填充到數組中,然后構造數據框。


mydict={('A', 'E'): 23972,

 ('A', 'D'): 10730,

 ('A', 'B'): 14748,

 ('A', 'C'): 3424,

 ('E', 'D'): 3294,

 ('E', 'B'): 16016,

 ('E', 'C'): 3373,

 ('D', 'B'): 69734,

 ('D', 'C'): 4662,

 ('B', 'C'): 159161}

 

import numpy as np

import pandas as pd


a = np.full((5,5),0)

ss = 'ABCDE'


for k, i in mydict.items():

    f,s = k 

    fi = ss.index(f)

    si = ss.index(s)

    a[fi,si] = i

    a[si,fi] = i


# if you want to keep the diagonal

df = pd.DataFrame(a)


# if you want to remove diagonal:

no_diag = np.delete(a,range(0,a.shape[0]**2,(a.shape[0]+1))).reshape(a.shape[0],(a.shape[1]-1))


df = pd.DataFrame(no_diag)


查看完整回答
反對 回復 2023-07-05
?
SMILET

TA貢獻1796條經驗 獲得超4個贊

一旦從字典中創建一個系列,然后unstack獲取一個數據幀。獲取union索引和列,以便能夠reindex同時獲取所有可能的值。將此數據幀的轉置添加到自身以查找缺失值。


df_ = pd.Series(mydict).unstack(fill_value=0)

idx = df_.index.union(df_.columns)

df_ = df_.reindex(index=idx, columns=idx, fill_value=0)

df_ += df_.T


print(df_)

       A       B       C      D      E

A      0   14748    3424  10730  23972

B  14748       0  159161  69734  16016

C   3424  159161       0   4662   3373

D  10730   69734    4662      0   3294

E  23972   16016    3373   3294      0


查看完整回答
反對 回復 2023-07-05
  • 4 回答
  • 0 關注
  • 197 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號