[英]How to efficiently flatten a dictionary of Sorted dictionaries to numpy.arrays
我想知道是否有更有效的方法來展平我的數據。 請參見以下扁平化數據結構的示例:
{t: SortedDict(
{0: {'t': 5, 'ids': [{'1': ['data']}]},
1: {'t': 2, 'ids': [{'1': ['data']}]},
2: {'t': 4, 'ids': [{'1': ['data']}]},
3: {'t': 1, 'ids': [{'1': ['data']}]},
4: {'t': 4, 'ids': [{'1': ['data']}]},
5: {'t': 1, 'ids': [{'1': ['data']}]},
6: {'t': 3, 'ids': [{'1': ['data']}]},
7: {'t': 2, 'ids': [{'1': ['data']}]},
8: {'t': 1, 'ids': [{'1': ['data']}]},
9: {'t': 1, 'ids': [{'1': ['data']}]}
}),t:SortedDict(
{
27: {'t': 1, 'ids': [{'5': ['data','data']}]},
28: {'t': 1, 'ids': [{'5': ['data','data','data','data']}]},
29: {'t': 2, 'ids': [{'5': ['data','data']}]},
30: {'t': 1, 'ids': [{'5': ['data']}]},
31: {'t': 2, 'ids': [{'5': ['data','data','data','data']}]},
32: {'t': 1, 'ids': [{'5': ['data']}]}
})}
注意:SortedDict 來自 Sorted Containers 庫,它是 Apache2 許可的 Python 排序 collections。
我評估了其他幾個 stackoverflow 帖子,它們與列表理解或 lambda function 做類似的事情。 最終,我寫了一個方法,將字典扁平化為三個列表; 但是,我不確定這種方法是否是最佳方法。 方法如下:
def flatten(self, d,calculation_dict):
l_key = [] # Stores linearized keys
l_results = [] # Stores linearized values after calculation
index = [] # Stores the start of each individual sub-array
i = 0
for val in d.values():
index.append(i)
for key, t in val.t.items():
#Add calculation in here since I am Iterating over every element
l_results.append(t["t"] * calculation_dict[key])
l_key.append(key)
i += 1
h_index = numpy.array(index, dtype=numpy.int32)
h_l_results = numpy.array(l_results,dtype=numpy.float)
l_key = numpy.array(l_key, dtype=numpy.int32)
index.append(i)
return (l_key,l_results,index)
#Need output to be numpy.array
l_key = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 27, 28, 29, 30, 31, 32]
l_results = [5.0, 2.0, 4.0, 1.0, 4.0, 1.0, 3.0, 3.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 2.0, 1,0]
index = [0, 10]
在我的應用程序中速度是極其重要的。 因此,任何反饋或建議將不勝感激。
編輯:忘了提到我需要在 numpy 數組中的最終結果。 不確定這是否會改變任何事情。
編輯:感謝 Glauco 的建議,我將扁平化方法修改如下:
def flatten_numpy(self, d,calculation_dict):
l_results = numpy.empty(self.size,dtype=numpy.float)
l_key = numpy.empty(self.size, dtype=numpy.int32)
index = []
i = 0
for val in d.values():
index.append(i)
for key, t in val.t.items():
l_results[i] = (tf["tf"] * idf[term])
l_key[i] = term
i += 1
index.append(i)
h_index = numpy.array(index, dtype=numpy.int32)
return (l_key,l_results,index)
事實證明,在算法的早期,我已經不得不訪問每個子字典的大小。 利用這一點,我開始累積這個值大小變量,在測試新方法后它會稍微快一些。 測試結果如下:
#Each Test was executed on the different data and ran 1000 times
Test#1 | Flatten 6.422301292419434 | Flatten_numpy 4.761376142501831
Test#2 | Flatten 5.212526082992554 | Flatten_numpy 4.901215553283691
Test#3 | Flatten 5.2060017585754395 | Flatten_numpy 5.266955852508545
Test#4 | Flatten 6.079436302185059 | Flatten_numpy 4.803238153457642
Test#5 | Flatten 5.059106349945068 | Flatten_numpy 4.565468788146973
您的方法在算法上是正確的,它是 O(n+m) 它是線性的,沒有其他方法。 如果您知道 haom 許多 dict 將從集群到達,那么創建空的 numpy 數據結構並在運行時填充它會更方便,避免列表附加。
最后, t計算:
l_results.append(t["t"] * calculation_dict[key])
可以使用 arrays 快速完成,在收集階段的底部
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.