Tl; dr是大胆的文字.
我正在处理一个带有布尔"一热"图像注释的图像数据集(Celeba具体).注释编码面部特征,如秃头,男性,年轻.现在我想制作一个自定义的热门列表(测试我的GAN模型).我想提供一个有文化的界面.也就是说,而不是指定features[12]=True知道12- 从零开始计数 - 对应于男性特征,我想要的东西像features[male]=True或features.male=True.
假设我的.txt文件的标题是
Arched_Eyebrows Attractive Bags_Under_Eyes Bald Bangs Chubby Male Wearing_Necktie Young
Run Code Online (Sandbox Code Playgroud)
我想编纂Young,Bald和Chubby.预期的产出是
[ 0. 0. 0. 1. 0. 1. 0. 0. 1.]
Run Code Online (Sandbox Code Playgroud)
因为Bald是标题的第四个条目,Chubby是第六个,依此类推.在没有期望用户知道Bald是第四个条目等的情况下,最明智的方法是什么?
我正在寻找一种Pythonic方式,不一定是最快的方式.
粗略的重要性:
.txt标题中的属性.这是我想要设计的重点.aenum..txt属性名称/可用属性的标头.一个例子:如果用户想要指定性别属性但不知道是否使用male或female,则应该很容易找到.dir()足以满足这一点.我将比较和对比立即出现在我脑海中的方式.所有例子都使用:
import numpy as np
header = ("Arched_Eyebrows Attractive Bags_Under_Eyes "
"Bald Bangs Chubby Male Wearing_Necktie Young")
NUM_CLASSES = len(header.split()) # 9
Run Code Online (Sandbox Code Playgroud)
显然我们可以用字典来完成这个:
binary_label = np.zeros([NUM_CLASSES])
classes = {head: idx for (idx, head) in enumerate(header.split())}
binary_label[[classes["Young"], classes["Bald"], classes["Chubby"]]] = True
print(binary_label)
Run Code Online (Sandbox Code Playgroud)
对于它的价值,它拥有最少的代码行,并且是唯一一个不依赖于内置的标准库的代码.至于否定,它并不完全是自我记录.要查看可用选项,您必须print(classes.keys())- 它不会暴露dir().这边界不满足特征5,因为它要求用户知道classes曝光特征AFAIK的字典.
因为我现在正在学习C++,Enum所以首先想到的是:
import enum
binary_label = np.zeros([NUM_CLASSES])
Classes = enum.IntEnum("Classes", header)
features = [Classes.Young, Classes.Bald, Classes.Chubby]
zero_idx_feats = [feat-1 for feat in features]
binary_label[zero_idx_feats] = True
print(binary_label)
Run Code Online (Sandbox Code Playgroud)
这给出了点符号,并且图像选项被曝光dir(Classes).但是,enum默认情况下使用单索引(原因记录在案).解决方法让我觉得enum不是Pythonic这样做的方式,完全不能满足功能6.
这是标准Python库中的另一个:
import collections
binary_label = np.zeros([NUM_CLASSES])
clss = collections.namedtuple(
"Classes", header)._make(range(NUM_CLASSES))
binary_label[[clss.Young, clss.Bald, clss.Chubby]] = True
print(binary_label)
Run Code Online (Sandbox Code Playgroud)
使用namedtuple,我们再次获得点符号和自我文档dir(clss).但是,namedtuple班级比重enum.我的意思是,这是namedtuple我不需要的功能.这个解决方案似乎是我的例子中的领导者,但我不知道它是否满足功能1或者是否可以通过功能7"赢得".
我真的可以打破我的背影:
binary_label = np.zeros([NUM_CLASSES])
class Classes(enum.IntEnum):
Arched_Eyebrows = 0
Attractive = 1
Bags_Under_Eyes = 2
Bald = 3
Bangs = 4
Chubby = 5
Male = 6
Wearing_Necktie = 7
Young = 8
binary_label[
[Classes.Young, Classes.Bald, Classes.Chubby]] = True
print(binary_label)
Run Code Online (Sandbox Code Playgroud)
这具有Ex的所有优点.但是,它有明显的明显缺点.我必须写出所有的功能(真实数据集中有40个)才能实现零索引!当然,这是如何在C++(AFAIK)中创建枚举,但它在Python中不是必需的.这是功能6的轻微故障.
有许多方法可以在Python中实现文字零索引.你会提供一个代码片段,告诉我你将如何完成我所追求的目标并告诉我为什么你的方式是正确的?
(编辑:) 或解释为什么我的一个例子是适合这项工作的工具?
如果有人想要解决以下反馈/更新,或者出现任何新的解决方案,我还没准备好接受答案.也许另外24小时?所有的回复都很有帮助,所以到目前为止,我对所有人都赞不绝口.你可能想查看我用于测试解决方案的这个回购.如果我的以下言论准确或不公平,请随时告诉我:
奇怪的是,Sphinx错误地记录了这个(在文档中是一个索引),但它确实记录了它!我认为"问题"不会失败任何理想的功能.
我觉得这有点Map矫枉过正,但是dotdict可以接受.感谢两位使用此解决方案的回答者dir().然而,它似乎并没有与Sphinx"无缝地"工作.
如上所述,此解决方案比其他解决方案花费更长的时间.它比一个namedtuple(比纯粹的dict落后最快)慢10倍,比标准IntEnum慢7倍(在numpy记录后面最慢).这在当前规模上并不是激烈的,也不是优先事项,但谷歌快速搜索表明np.in1d实际上很慢.让我们坚持下去
_label = np.zeros([NUM_CLASSES])
_label[[header_rec[key].item() for key in ["Young", "Bald", "Chubby"]]] = True
Run Code Online (Sandbox Code Playgroud)
除非我在链接的回购中实现了错误.这使执行速度进入与其他解决方案相比较的范围.再一次,没有Sphinx.
我不相信你的enum批评.在我看来,你相信我正在接近这个问题.可以打电话给我,但我不知道如何使用它namedtuple与"Enum [哪个]将为每个常量提供单独的值"有根本的不同.我误会了你吗?
无论如何,namedtuple出现在Sphinx中(正确编号,为了它的价值).在理想特征列表中,这与零枚举前的零枚举和配置文件完全相同.
我接受了零回答,因为答案给了我最好的挑战namedtuple.按照我的标准,namedtuple勉强是最好的解决方案.但salparadise写了答案,让我对这个评估有信心.感谢所有回答的人.
工厂函数如何创建一个零索引的对象IntEnum,因为它适合您的需求,并Enum提供构造的灵活性:
from enum import IntEnum
def zero_indexed_enum(name, items):
# splits on space, so it won't take any iterable. Easy to change depending on need.
return IntEnum(name, ((item, value) for value, item in enumerate(items.split())))
Run Code Online (Sandbox Code Playgroud)
然后:
In [43]: header = ("Arched_Eyebrows Attractive Bags_Under_Eyes "
...: "Bald Bangs Chubby Male Wearing_Necktie Young")
In [44]: Classes = zero_indexed_enum('Classes', header)
In [45]: list(Classes)
Out[45]:
[<Classes.Arched_Eyebrows: 0>,
<Classes.Attractive: 1>,
<Classes.Bags_Under_Eyes: 2>,
<Classes.Bald: 3>,
<Classes.Bangs: 4>,
<Classes.Chubby: 5>,
<Classes.Male: 6>,
<Classes.Wearing_Necktie: 7>,
<Classes.Young: 8>]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
467 次 |
| 最近记录: |