我正在将一个相当大的数据集从json解析为"传统的"数据框(作为观察的行,作为变量的列)。 json对象包含每个观察的特征列表。我想将其转换为零一向量,表明所讨论的观察是否具有该特征。
我所拥有的是"主列表" (所有可能特征的列表)和观察列表(如json dicts)。设所有特征的数量为K.每个观测值的输出应为长度为K的零列表,标记每个特征是否适用于该观测值。
我目前的做法是“蛮力”#34;迭代:
characteristics #master list of all possibilities
output_dataset = []
for observation in data:
chars = observation["characteristics"]
vector = [ int(chr in chars) for chr in characteristics ]
output_dataset.append(vector)
然而,当特征数量达到数千且观察数量达到数万时,这在计算上相当昂贵。
是否有更有效的方法(通常,或者特别是在Python / Numpy / Pandas中)?
更新
为了清楚起见,作为一个例子,这里有不同的变量应该是什么样的。 (想象一下观察结果是移动设备。)
主列表: ["android", "ios", "windows", "phone", "tablet", "dual-sim", "fingerprint", "nfc", "usb-c", "lg", "samsung", "huawei", "htc", "motorola", "apple", "google", "nokia"...]
一个观察结果: ["android", "phone", "fingerprint", "nfc", "lg"...]
所需的输出向量: [1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,...]
答案 0 :(得分:0)
我不完全确定我理解这一点,但我认为你想用dict。 dict是对任意键值执行查找的有效方式。查找长度为N的列表中的键是O(N),通过哈希表优化查找词典中的键。根据算法和可用内存,在O(1)和O(ln N)之间。
所以,首先将特征转换为dict,将特征映射到索引号,索引numnber在characteristics
chardict = {}
for i,v in enumerate(characteristics):
chardict[v] = i
现在您可以有效地将特征映射到向量中正确位置的1
vector = [0] * len(characteristics) # initialize all zero, correct length
for k in observation["characteristics"]:
if k in chardict:
vector[ chardict[k]] = 1
使用dict的get
方法可能更有效,这样您现在或以后也可以检查错误的输入数据。但不太清楚。
L = len(characteristics)
vector = [0] * (L+1) # last bin for junk input
for k in observation["characteristics"]:
vector[ chardict.get(k, L) ] = 1
if vector[L]:
# there was an input not known to characteristics ....
del vector[L] # get rid of the last element if no longer wanted