在做分析时,处理近2G的一个CSV文件,10G内存的机器感觉内存不够用,找到了这个函数,效果很好,尤其是对大量使用数字类型的数据,主要原理是把int64/float64类型的数值用更小的int(float)32/16/8来搞定,拿走直接用,经常会减少50%的内存使用,甚至更多。
使用方法:
df = pd.read_csv(file)
reduce_mem_usage(df)
函数如下:
Python Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
|
import pandas as pd
import numpy as np
# @liscense: Apache 2.0
# @author: weijian def reduce_mem_usage(props):
# 计算当前内存
start_mem_usg = props.memory_usage().sum() / 1024 ** 2
print("Memory usage of the dataframe is :", start_mem_usg, "MB")
# 哪些列包含空值,空值用-999填充。why:因为np.nan当做float处理
NAlist = []
for col in props.columns:
# 这里只过滤了objectd格式,如果你的代码中还包含其他类型,请一并过滤
if (props[col].dtypes != object):
print("**************************")
print("columns: ", col)
print("dtype before", props[col].dtype)
# 判断是否是int类型
isInt = False
mmax = props[col].max()
mmin = props[col].min()
# Integer does not support NA, therefore Na needs to be filled
if not np.isfinite(props[col]).all():
NAlist.append(col)
props[col].fillna(-999, inplace=True) # 用-999填充
# test if column can be converted to an integer
asint = props[col].fillna(0).astype(np.int64)
result = np.fabs(props[col] - asint)
result = result.sum()
if result < 0.01: # 绝对误差和小于0.01认为可以转换的,要根据task修改
isInt = True
# make interger / unsigned Integer datatypes
if isInt:
if mmin >= 0: # 最小值大于0,转换成无符号整型
if mmax <= 255:
props[col] = props[col].astype(np.uint8)
elif mmax <= 65535:
props[col] = props[col].astype(np.uint16)
elif mmax <= 4294967295:
props[col] = props[col].astype(np.uint32)
else:
props[col] = props[col].astype(np.uint64)
else: # 转换成有符号整型
if mmin > np.iinfo(np.int8).min and mmax < np.iinfo(np.int8).max:
props[col] = props[col].astype(np.int8)
elif mmin > np.iinfo(np.int16).min and mmax < np.iinfo(np.int16).max:
props[col] = props[col].astype(np.int16)
elif mmin > np.iinfo(np.int32).min and mmax < np.iinfo(np.int32).max:
props[col] = props[col].astype(np.int32)
elif mmin > np.iinfo(np.int64).min and mmax < np.iinfo(np.int64).max:
props[col] = props[col].astype(np.int64)
else: # 注意:这里对于float都转换成float16,需要根据你的情况自己更改
props[col] = props[col].astype(np.float16)
print("dtype after", props[col].dtype)
print("********************************")
print("___MEMORY USAGE AFTER COMPLETION:___")
mem_usg = props.memory_usage().sum() / 1024 ** 2
print("Memory usage is: ", mem_usg, " MB")
print("This is ", 100 * mem_usg / start_mem_usg, "% of the initial size")
return props, NAlist
|
加载中,请稍候......