Câu hỏi của tôi không phải về một đoạn mã cụ thể nhưng tổng quát hơn, vì vậy hãy chịu theo tôi:python: kỹ thuật hiệu quả để xử lý dữ liệu lồng nhau sâu một cách linh hoạt là gì?
Tôi nên tổ chức dữ liệu như thế nào và sử dụng công cụ nào để quản lý?
Tôi đang sử dụng python và numpy để phân tích dữ liệu. Bởi vì tài liệu python chỉ ra rằng các từ điển rất được tối ưu hóa trong python, và cũng do thực tế là dữ liệu chính nó là rất có cấu trúc, tôi đã lưu nó trong một từ điển lồng nhau sâu sắc.
Đây là một bộ xương của các từ điển: vị trí trong hệ thống phân cấp xác định tính chất của nguyên tố này, và mỗi dòng mới xác định nội dung của một quan trọng trong mức tiền lệ:
[AS091209M02] [AS091209M01] [AS090901M06] ...
[100113] [100211] [100128] [100121]
[R16] [R17] [R03] [R15] [R05] [R04] [R07] ...
[1263399103] ...
[ImageSize] [FilePath] [Trials] [Depth] [Frames] [Responses] ...
[N01] [N04] ...
[Sequential] [Randomized]
[Ch1] [Ch2]
Edit: Để giải thích một chút tốt hơn thiết lập dữ liệu của tôi:
[individual] ex: [AS091209M02]
[imaging session (date string)] ex: [100113]
[Region imaged] ex: [R16]
[timestamp of file] ex [1263399103]
[properties of file] ex: [Responses]
[regions of interest in image ] ex [N01]
[format of data] ex [Sequential]
[channel of acquisition: this key indexes an array of values] ex [Ch1]
các loại hoạt động tôi thực hiện là ví dụ để tính toán tính chất của các mảng (được liệt kê dưới Ch1, CH2), nhặt mảng để thực hiện một bộ sưu tập mới, ví dụ phân tích phản ứng của N01 từ vùng 16 (R16) của một indi cụ thể vidual tại các thời điểm khác nhau, v.v.
Cấu trúc này hoạt động tốt cho tôi và rất nhanh, như đã hứa. Tôi có thể phân tích tập dữ liệu đầy đủ khá nhanh (và từ điển quá nhỏ để lấp đầy ram của máy tính của tôi: nửa buổi biểu diễn).
Sự cố của tôi xuất phát từ cách cồng kềnh mà tôi cần phải lập trình các hoạt động của từ điển. Tôi thường có những đoạn mã mà đi như thế này:
for mk in dic.keys():
for rgk in dic[mk].keys():
for nk in dic[mk][rgk].keys():
for ik in dic[mk][rgk][nk].keys():
for ek in dic[mk][rgk][nk][ik].keys():
#do something
đó là xấu xí, cồng kềnh, không thể tái sử dụng, và giòn (cần phải mã hóa lại nó cho bất kỳ biến thể của từ điển).
Tôi đã thử sử dụng các hàm đệ quy, nhưng ngoài các ứng dụng đơn giản nhất, tôi đã gặp phải một số lỗi rất khó chịu và các hành vi kỳ lạ gây ra lãng phí thời gian (không giúp tôi gỡ lỗi với pdb trong ipython khi tôi xử lý các hàm đệ quy lồng nhau sâu sắc). Cuối cùng chức năng đệ quy duy nhất mà tôi sử dụng thường xuyên như sau:
def dicExplorer(dic, depth = -1, stp = 0):
'''prints the hierarchy of a dictionary.
if depth not specified, will explore all the dictionary
'''
if depth - stp == 0: return
try : list_keys = dic.keys()
except AttributeError: return
stp += 1
for key in list_keys:
else: print '+%s> [\'%s\']' %(stp * '---', key)
dicExplorer(dic[key], depth, stp)
Tôi biết tôi đang làm điều này sai, bởi vì mã của tôi là dài, noodly và không thể tái sử dụng. Tôi cần phải sử dụng các kỹ thuật tốt hơn để thao tác linh hoạt các từ điển, hoặc để đưa dữ liệu vào một số định dạng cơ sở dữ liệu (sqlite?). Vấn đề của tôi là vì tôi (kém) tự học về lập trình, tôi thiếu kinh nghiệm thực tế và kiến thức nền tảng để đánh giá cao các tùy chọn có sẵn. Tôi đã sẵn sàng để học các công cụ mới (SQL, lập trình hướng đối tượng), bất cứ điều gì cần để hoàn thành công việc, nhưng tôi miễn cưỡng đầu tư thời gian và nỗ lực vào thứ gì đó sẽ là một kết thúc chết cho nhu cầu của mình.
Vì vậy, các đề xuất của bạn để giải quyết vấn đề này là gì và có thể mã hóa công cụ của tôi theo cách ngắn gọn, linh hoạt và có thể sử dụng lại được không?
Phụ Lục: ngoài làm cái gì đó với một tiểu từ điển đặc biệt của từ điển dữ liệu, đây là một số ví dụ về các hoạt động tôi thực hiện cho dic bộ dữ liệu, hoặc một cuốn từ điển phụ của nó:
thực sự tôi có một số đệ quy chức năng hoạt động tốt:
def normalizeSeqDic(dic, norm_dic = {}, legend =()):
'''returns a normalized dictionary from a seq_amp_dic. Normalization is performed using the first time point as reference
'''
try :
list_keys = dic.keys()
for key in list_keys:
next_legend = legend + (key,)
normalizeSeqDic(dic[key], norm_dic, next_legend)
except AttributeError:
# normalization
# unpack list
mk, ek, nk, tpk = legend
#assign values to amplitude dict
if mk not in norm_dic: norm_dic[mk] = {}
if ek not in norm_dic[mk]: norm_dic[mk][ek] = {}
if nk not in norm_dic[mk][ek]: norm_dic[mk][ek][nk] = {}
if tpk not in norm_dic[mk][ek][nk]: norm_dic[mk][ek][nk][tpk] = {}
new_array = []
for x in range(dic.shape[0]):
new_array.append(dic[x][1:]/dic[x][0])
new_array = asarray(new_array)
norm_dic[mk][ek][nk][tpk] = new_array
return norm_dic
def poolDic(dic):
'''returns a dic in which all the values are pooled, and root (mk) keys are fused
these pooled dics can later be combined into another dic
'''
pooled_dic = {}
for mk in dic.keys():
for ek in dic[mk].keys():
for nk in dic[mk][ek].keys():
for tpk in dic[mk][ek][nk].keys():
#assign values to amplitude dict
if ek not in pooled_dic: pooled_dic[ek] = {}
if nk not in pooled_dic[ek]: pooled_dic[ek][nk] = {}
if tpk not in pooled_dic[ek][nk]:
pooled_dic[ek][nk][tpk] = dic[mk][ek][nk][tpk]
else: pooled_dic[ek][nk][tpk]= vstack((pooled_dic[ek][nk][tpk], dic[mk][ek][nk][tpk]))
return pooled_dic
def timePointsDic(dic):
'''Determines the timepoints for each individual key at root
'''
tp_dic = {}
for mk in dic.keys():
tp_list = []
for rgk in dic[mk].keys():
tp_list.extend(dic[mk][rgk]['Neuropil'].keys())
tp_dic[mk]=tuple(sorted(list(set(tp_list))))
return tp_dic
đối với một số hoạt động tôi thấy không có cách nào khác ngoài việc làm phẳng các từ điển:
def flattenDic(dic, label):
'''flattens a dic to produce a list of of tuples containing keys and 'label' values
'''
flat_list = []
for mk in dic.keys():
for rgk in dic[mk].keys():
for nk in dic[mk][rgk].keys():
for ik in dic[mk][rgk][nk].keys():
for ek in dic[mk][rgk][nk][ik].keys():
flat_list.append((mk, rgk, nk, ik, ek, dic[mk][rgk][nk][ik][ek][label])
return flat_list
def extractDataSequencePoints(flat_list, mk, nk, tp_list):
'''produces a list containing arrays of time point values
time_points is a list of the time points wished (can have 2 or 3 elements)
'''
nb_tp = len(tp_list)
# build tp_seq list
tp_seq = []
tp1, tp2, tp3 = [], [], []
if nk == 'Neuropil':
tp1.extend(x for x in flat_list if x[0]==mk and x[2] == 'Neuropil' and x[3] == tp_list[0])
tp2.extend(x for x in flat_list if x[0]==mk and x[2] == 'Neuropil'and x[3] == tp_list[1])
else:
tp1.extend(x for x in flat_list if x[0]==mk and x[2] != 'Neuropil'and x[3] == tp_list[0])
tp2.extend(x for x in flat_list if x[0]==mk and x[2] != 'Neuropil'and x[3] == tp_list[1])
if nb_tp == 3:
if nk == 'Neuropil':
tp3.extend(x for x in flat_list if x[0]==mk and x[2] == 'Neuropil'and x[3] == tp_list[2])
else:
tp3.extend(x for x in flat_list if x[0]==mk and x[2] != 'Neuropil'and x[3] == tp_list[2])
for x in tp1:
for y in tp2:
if x[0:3] == y[0:3] :
if nb_tp == 3:
for z in tp3:
if x[0:3] == z[0:3] :
tp_seq.append(asarray([x[4],y[4],z[4]]))
else:
tp_seq.append(asarray([x[4],y[4]]))
return tp_seq
@AlexandreS: Tôi e rằng tôi không thực sự hiểu đủ về dữ liệu mẫu của bạn để có thể đưa ra nhiều lời khuyên. Bạn có thể xây dựng dữ liệu mà bạn đang phân tích và phân tích những gì bạn đang thực hiện? – MattH
@MattH: Tôi đã chỉnh sửa câu hỏi để cung cấp thêm chi tiết. Hãy cho tôi biết nếu nó không đủ – AlexandreS
@ AlexandrS: Cảm ơn bạn đã làm rõ. Nó có thể giúp thêm nếu bạn có thể giải thích cách dữ liệu này được mua/lưu trữ/xuất phát tại thời điểm này. Tôi nghĩ rằng con đường phía trước sẽ là để bạn tạo ra một sơ đồ trừu tượng của bạn được cấu trúc như các đối tượng với các thuộc tính và cách các đối tượng/thuộc tính liên quan đến nhau. Khi tôi quyết định làm thế nào để mã hóa một cấu trúc dữ liệu, tôi sẽ thường phác thảo ra những điều này. – MattH