首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何快速将蒙面数组应用于非常大的JSON

如何快速将蒙面数组应用于非常大的JSON
EN

Stack Overflow用户
提问于 2020-03-21 02:09:22
回答 2查看 89关注 0票数 1

数据

我目前正在处理非常大的JSON文件,格式如下

代码语言:javascript
运行
复制
{key: [1000+ * arrays of length 241],
 key2: [1000+ * arrays of length 241],
 (...repeat 5-8 times...)}

数据的结构方式是每个键数组中的nth元素属于nth实体。把它想象成每个键都是一个描述符,比如“高度”或“压力”。因此,要获得实体的“高度”和“压力”,可以访问所有数组中的实体索引n。因此,所有键的数组都是相同长度的Z

正如你所能想象的,这是一种整体上的痛苦。因此,每当我执行任何数据操作时,我都会返回一个长度为Z的蒙面数组,该数组由1和0填充。1表示该索引中的每个键中的数据将被保留,0表示应该省略它)

问题

一旦执行了所有数据操作,我需要将蒙面数组应用于数据以返回原始JSON数据的副本,但其中每个键的数组Z的长度等于掩码数组中的1's数(如果在索引n处的蒙面数组中的元素为0,则索引n中的元素将从json键的所有数组中移除,反之亦然)

我的尝试

代码语言:javascript
运行
复制
# mask: masked array
# d: data to apply the mask to
 def apply_mask(mask, d):
    keys = d.keys()
    print(keys)
    rem = [] #List of index to remove
    for i in range(len(mask)):
        if mask[i] == 0:
            rem.append(i) #Populate 'rem'

        for k in keys:
            d[k] = [elem for elem in d[k] if not d[k].index(elem) in rem]

    return d

这按照预期工作,但在这样大的JSON数据上需要一段时间。

问题

我希望上面的一切都是清楚的,并帮助你理解我的问题:

是否有一种更优/更快的方法将蒙面数组应用于数据,如上面所示?

干杯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-21 03:04:51

这会很慢,因为

代码语言:javascript
运行
复制
d[k] = [elem for elem in d[k] if not d[k].index(elem) in rem]

每次都是完全重新创建内部列表。

由于您已经对d进行了就地修改,所以只需删除相应的元素:

代码语言:javascript
运行
复制
def apply_mask(mask, d):
    for i, keep in enumerate(mask):
        if not keep:
            for key in d:
                del d[key][i - len(mask)]
    return d

(之所以使用负索引i - len(mask),是因为如果列表已经由于先前删除的元素而更改其长度,则正索引不再起作用。)

票数 1
EN

Stack Overflow用户

发布于 2020-03-21 11:48:52

这个问题来自于代码的高算法复杂性。设计一种更快的算法是可能的。

设K是字典d中的键数。len(d))。让Z当面具的大小。len(mask)),它也是d中数组值的典型大小(即任何keylen(d[key]))。

初始代码的算法复杂度为O(Z^3 * K).。这是因为rem是一个列表,in rem是用线性时间完成的,也是因为d[k].index(elem)d[k]中搜索elem的时间也是线性的。

费恩福特提出的解决方案更快。实际上,他的代码的复杂性是O(Z^2 * K) (因为del是在CPython列表上以线性时间完成的)。

但是,可以在线性时间内进行计算:O(K * Z).。以下是如何:

代码语言:javascript
运行
复制
def apply_mask(mask, d):
    for key in d:
        d[key] = [e for i,e in enumerate(d[key]) if mask[i]!=0]
    return d

这段代码应该更快几个数量级。

PS:我认为初始算法对于问题的描述是不正确的。实际上,应该保留的一些项可以被删除,因为在迭代之间没有清除rem (所以索引是累积的)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60783816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档