问题描述
好的,所以我有一个正在处理的项目,但我无法弄清楚。 如果之前有人问过这个问题,我很抱歉,我已经搜索过但一无所获。 这是我的第一篇文章。
我有一些 Pandas 数据框,我想根据我设置的哈希值访问它们:
df = defaultdict(lambda: defaultdict(dict))
or
df = defaultdict(dict)
我这样做是为了我可以根据用例索引 df['a']['1'][1]
或 df['a'][1]
。
请注意,“矩阵”的形状不一定相等。所以
df['a']['2'][1]
可能存在但不存在 df['b']['2'][1]
。
TLDR
我想使用 ['a','2',1] 或 ['a',1] 之类的列表访问 df
我做了什么:
老方法:
我过去常常创建主列表,然后我会对其进行迭代和检查。这有效,但我觉得它非常丑陋。上述两个用例也不同。我现在正在尝试围绕上述两个用例进行包装。我希望包装器不会成为这两个用例的大开关。
x_master_list = []
y_master_list = []
for x in df:
if x not in x_master_list:
x_master_list.append(channel)
for y in df[x]:
if y not in y_master_list:
y_master_list.append(idx)
for y in y_master_list:
for x in x_master_list:
if x in df:
if y in df[x]:
较新的方式:
我发现一个 link 讨论使用递归来获取所有键。这很好,因为它保留了层次结构的顺序。
def iter_leafs(d,keys=[]):
for key,val in d.items():
if isinstance(val,defaultdict) | isinstance(val,dict):
yield from iter_leafs(val,keys + [key])
else:
yield keys + [key]
我将主列表的创建修改为:
def create_master_lists(type,df):
check_type(type)
lists = master_lists[type]
key_list = list(iter_leafs(df))
for key in key_list:
for idx,list in enumerate(lists):
if key[idx] not in list:
list.append(key[idx])
return lists
现在我想做如下事情:
key_list = list(iter_leafs(df))
for y in y_master_list:
valid_idx_keys = [key for key in keylist if key[-1] == y]
这里的 key_list 看起来像 [['a','1',0],['a',1],etc]
而 valid_idx_keys 基本上是一个过滤版本。
我想从 valid_idx_keys 中获取每个列表并访问 df。我不知道如何实现这一点。
如果我执行以下操作,它会起作用,但同样重要的是围绕两个索引参数数量不同的用例进行包装。
for x,y,z in valid_idx_keys:
df[x][y][z]
也许是递归的东西,为子列表中的每个元素慢慢地向下移动一层?我仍在尝试一些事情,但我想在这里发帖,以防有人有办法实现这一目标或更好地解决我的问题。
解决方法
所以我最终得到了以下内容。它有效,但我愿意接受建议。
from collections import defaultdict
def search_dict(d,list):
key = list[0]
val = d.get(key)
if isinstance(val,defaultdict) | isinstance(val,dict):
yield from search_dict(val,list[1:])
else:
yield val
df = defaultdict(lambda: defaultdict(dict))
df['a']['1'][1] = 0
df['b']['1'][1] = 1
test_key_list = [['a','1',1],['b',1]]
print(list(search_dict(df,test_key_list[0])))
print(list(search_dict(df,test_key_list[1])))
vals = []
for lis in test_key_list:
print(lis)
vals = vals + list(search_dict(df,lis))
print(vals)
df2 = defaultdict(dict)
df2['a'][1] = 0
df2['b'][1] = 1
test_key_list2 = [['a',1]]
vals = []
for lis in test_key_list2:
print(lis)
vals = vals + list(search_dict(df2,lis))
print(vals)