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

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 的方法是最快的。

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)

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
添加回答
舉報