我正在创建一个读取二进制文件并返回可用于初始化@Component({
selector: 'registry_form',
template:
'
<label for="name">name {{model}}</label>
<input [(ngModel)]="model" required >
',
styleUrls: [...],
directives: [...]
})
export class RegistryFormComponent
{
@Input() model;
}
的数据的包,我现在想知道是否最好返回DataFrame
或两个列表(一个持有钥匙和持有价值的钥匙)。
我正在制作的软件包不应该完全依赖于dict
对象,这就是为什么我的软件包当前将数据输出为DataFrame
(为了便于访问)。如果可以节省一些内存和速度(这对我的应用程序至关重要,因为我处理数百万个数据点),我想输出密钥和值列表。然后,这些迭代将用于初始化dict
。
这是一个简单的例子:
DataFrame
据我了解,In [1]: d = {(1,1,1): '111',
...: (2,2,2): '222',
...: (3,3,3): '333',
...: (4,4,4): '444'}
In [2]: keyslist=[(1,1,1),(2,2,2),(3,3,3),(4,4,4)]
In [3]: valslist=['111','222','333','444']
In [4]: import pandas as pd
In [5]: dfdict=pd.DataFrame(d.values(), index=pd.MultiIndex.from_tuples(d.keys(), names=['a','b','c']))
In [6]: dfdict
Out[6]:
0
a b c
3 3 3 333
2 2 2 222
1 1 1 111
4 4 4 444
In [7]: dflist=pd.DataFrame(valslist, index=pd.MultiIndex.from_tuples(keyslist, names=['a','b','c']))
In [8]: dfpair
Out[8]:
0
a b c
1 1 1 111
2 2 2 222
3 3 3 333
4 4 4 444
和d.values()
正在创建新的 副本 数据。如果我们忽略a d.keys()
需要更多内存然后使用dict
这一事实,使用list
和d.values()
会导致更多内存使用,那么d.keys()
对实现?
答案 0 :(得分:3)
我对1M行进行了内存分析。获胜的结构是对每个数字索引使用array.array和字符串列表(147MB数据和310MB转换为pandas)。
根据Python手册
数组是序列类型,其行为与列表非常相似,除此之外 存储在其中的对象类型受到约束。
他们甚至有附加方法,并且很可能具有非常快的追加速度。
第二位是两个单独的列表。 (308MB和450MB)
另外两个选项,使用dict并使用带有四元组的列表,是最糟糕的。字典:339MB,524MB。清单四:308MB,514MB。
以下是array.array:
的用法In [1]: from array import array
In [2]: import gc
In [3]: import pandas as pd
In [4]: %load_ext memory_profiler
In [5]: a1=array("l",range(1000000))
In [6]: a2=array("l",range(1000000))
In [7]: a3=array("l",range(1000000))
In [8]: b=[str(x*111) for x in list(range(1000000))]
In [9]: gc.collect()
Out[9]: 0
In [10]: %memit a1,a2,a3,b
peak memory: 147.64 MiB, increment: 0.32 MiB
In [11]: %memit dfpair=pd.DataFrame(b, index=pd.MultiIndex.from_arrays([a1,a2,a3], names=['a','b','c']))
peak memory: 310.60 MiB, increment: 162.91 MiB
以下是代码的其余部分(很长):
四元组列表:
In [1]: import gc
In [2]: import pandas as pd
In [3]: %load_ext memory_profiler
In [4]: a=list(zip(list(range(1000000)),list(range(1000000)),list(range(1000000))))
In [5]: b=[str(x*111) for x in list(range(1000000))]
In [6]: d2=[x+(b[i],) for i,x in enumerate(a)]
In [7]: del a
In [8]: del b
In [9]: gc.collect()
Out[9]: 0
In [10]: %memit d2
peak memory: 308.40 MiB, increment: 0.28 MiB
In [11]: %memit df = pd.DataFrame(d2, columns=['a','b','c','d']).set_index(['a','b','c'])
peak memory: 514.21 MiB, increment: 205.80 MiB
字典:
In [1]: import gc
In [2]: import pandas as pd
In [3]: %load_ext memory_profiler
In [4]: a=list(zip(list(range(1000000)),list(range(1000000)),list(range(1000000))))
In [5]: b=[str(x*111) for x in list(range(1000000))]
In [6]: d = dict(zip(a, b))
In [7]: del a
In [8]: del b
In [9]: gc.collect()
Out[9]: 0
In [10]: %memit d
peak memory: 339.14 MiB, increment: 0.23 MiB
In [11]: %memit dfdict=pd.DataFrame(list(d.values()), index=pd.MultiIndex.from_tuples(d.keys(), names=['a','b','c']))
peak memory: 524.10 MiB, increment: 184.95 MiB
两个阵列:
In [1]: import gc
In [2]: import pandas as pd
In [3]: %load_ext memory_profiler
In [4]: a=list(zip(list(range(1000000)),list(range(1000000)),list(range(1000000))))
In [5]: b=[str(x*111) for x in list(range(1000000))]
In [6]: gc.collect()
Out[6]: 0
In [7]: %memit a,b
peak memory: 307.75 MiB, increment: 0.19 MiB
In [8]: %memit dfpair=pd.DataFrame(b, index=pd.MultiIndex.from_tuples(a, names=['a','b','c']))
peak memory: 459.94 MiB, increment: 152.19 MiB
答案 1 :(得分:0)
以下是使用memory_profiler
的基准:
Filename: testdict.py
Line # Mem usage Increment Line Contents
================================================
4 66.2 MiB 0.0 MiB @profile
5 def testdict():
6
7 66.2 MiB 0.0 MiB d = {}
8
9 260.6 MiB 194.3 MiB for i in xrange(0,1000000):
10 260.6 MiB 0.0 MiB d[(i,i,i)]=str(i)*3
11
12 400.2 MiB 139.6 MiB dfdict=pd.DataFrame(d.values(), index=
pd.MultiIndex.from_tuples(d.keys(), names=['a','b','c']))
Filename: testlist.py
Line # Mem usage Increment Line Contents
================================================
4 66.5 MiB 0.0 MiB @profile
5 def testlist():
6
7 66.5 MiB 0.0 MiB keyslist=[]
8 66.5 MiB 0.0 MiB valslist=[]
9
10 229.3 MiB 162.8 MiB for i in xrange(0,1000000):
11 229.3 MiB 0.0 MiB keyslist.append((i,i,i))
12 229.3 MiB 0.0 MiB valslist.append(str(i)*3)
13
14 273.6 MiB 44.3 MiB dflist=pd.DataFrame(valslist, index=
pd.MultiIndex.from_tuples(keyslist, names=['a','b','c']))
对于相同的任务和内存类型,字典实现似乎并不具有内存效率。
出于某种原因,当我将值更改为数字数组(更能代表我的数据)时,我的表现非常相似,有谁知道为什么会这样?
Filename: testdict.py
Line # Mem usage Increment Line Contents
================================================
4 66.9 MiB 0.0 MiB @profile
5 def testdict():
6
7 66.9 MiB 0.0 MiB d = {}
8
9 345.6 MiB 278.7 MiB for i in xrange(0,1000000):
10 345.6 MiB 0.0 MiB d[(i,i,i)]=[0]*9
11
12 546.2 MiB 200.6 MiB dfdict=pd.DataFrame(d.values(), index=
pd.MultiIndex.from_tuples(d.keys(), names=['a','b','c']))
Filename: testlist.py
Line # Mem usage Increment Line Contents
================================================
4 66.3 MiB 0.0 MiB @profile
5 def testlist():
6
7 66.3 MiB 0.0 MiB keyslist=[]
8 66.3 MiB 0.0 MiB valslist=[]
9
10 314.7 MiB 248.4 MiB for i in xrange(0,1000000):
11 314.7 MiB 0.0 MiB keyslist.append((i,i,i))
12 314.7 MiB 0.0 MiB valslist.append([0]*9)
13
14 515.2 MiB 200.6 MiB dflist=pd.DataFrame(valslist, index=
pd.MultiIndex.from_tuples(keyslist, names=['a','b','c']))