根据包含键的列表访问 defaultdict(dict)
Access defaultdict(dict) based on list containing the keys
好的,我正在处理一个项目,但我无法解决这个问题。
如果之前有人问过这个问题,我深表歉意,我已经搜索过但一无所获。
这是我的第一个 post.
我有一些 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]:
较新的方式:
我发现 讨论使用递归来获取所有密钥。这很好,因为它保留了层次结构的顺序。
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',1], etc]
valid_idx_keys 基本上是过滤后的版本。
我想从 valid_idx_keys 中获取每个列表并访问 df。我不知道如何实现这一目标。
如果我执行以下操作,它会起作用,但重点还是要围绕两个没有相同数量索引参数的用例进行包装。
for x,y,z in valid_idx_keys:
df[x][y][z]
也许有一些递归的东西,可以为子列表中的每个元素慢慢地降低一层?我仍在尝试,但我想 post 以防万一有人有办法实现此目标或更好地解决我的问题。
所以我得到了以下结果。它有效,但我愿意接受建议。
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',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], ['b',1]]
vals = []
for lis in test_key_list2:
print(lis)
vals = vals + list(search_dict(df2, lis))
print(vals)
好的,我正在处理一个项目,但我无法解决这个问题。 如果之前有人问过这个问题,我深表歉意,我已经搜索过但一无所获。 这是我的第一个 post.
我有一些 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]:
较新的方式:
我发现
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',1], etc]
valid_idx_keys 基本上是过滤后的版本。
我想从 valid_idx_keys 中获取每个列表并访问 df。我不知道如何实现这一目标。
如果我执行以下操作,它会起作用,但重点还是要围绕两个没有相同数量索引参数的用例进行包装。
for x,y,z in valid_idx_keys:
df[x][y][z]
也许有一些递归的东西,可以为子列表中的每个元素慢慢地降低一层?我仍在尝试,但我想 post 以防万一有人有办法实现此目标或更好地解决我的问题。
所以我得到了以下结果。它有效,但我愿意接受建议。
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',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], ['b',1]]
vals = []
for lis in test_key_list2:
print(lis)
vals = vals + list(search_dict(df2, lis))
print(vals)