Python处理大数据的技巧, 2022-06-21

(2022.06.21 Tues)
收集整理了Python处理大量数据的方法,基于Pandas,Numpy等数据处理工具。

查看DataFrame占用的内存大小

用df的info方法并指定memory_usage='deep'参数,或使用df的memory_usage方法,并指定deep=True参数。

>> df = pandas.DataFrame([1,2,3])
>> df.info(memory_usage='deep')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 1 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   0       3 non-null      int64
dtypes: int64(1)
memory usage: 152.0 bytes
>> df_1.memory_usage(deep=True)
Index          132
Stkcd      4095000
...
Eranb       520000
dtype: int64

读取部分数据

读取excel/csv文件的前n行、特定位置开始的前n行

在读取数据文件的方法中加入nrows参数选择前n行数据读取。

>> df = pd.read_excel('tmpxxx.xls', nrows=200)
>> df.shape
(20, 41)

也可以跳过m行之后,读取从m行开始的n行

跳过前100行,读取10行,注意这里返回数据没有headers
>> df = pd.read_excel('tmpxxx.xls', skiprows=100, nrows=10)
>> df.columns # 以前一行的数据作为columns,而非整个excel的headers
Index(['1997', 123626, ...,103.5], dtype='object')

当然也可以在skiprows选项中指定范围,保留headers,即保留列名

>> df = pd.read_excel('tmpxxx.xls', skiprows=range(1, 100), nrows=10) 

可以指定skiprows中需要忽略的行,用list或array导入即可。下面是随机

>> lines = 1500000
>> skiplines = np.random.choice(np.arange(1, lines), size=lines-1-1000000, replace=False)
>> skiplines = np.sort(skiplines)
>> train = pd.read_csv('../input/train.csv', skiprows=skiplines)

如果在这个指令中忽略nrows=10指令,则读取跳过100行之后的所有数据。

指定读入的列

预先指定读入的列,缩小加载范围

>> columns = ['ip', 'click_time', 'is_attributed']
>> df = pd.read_excel('xxx.xls', usecols = columns)

指定/修改数据的读入类型/类型

不同的数据类型占用了不同大小的空间,对于尚未读取的数据,可以提前指定类型(dtype);对于已经读入的数据,通过astype方法修改成占空间更小的数据类型。

在读入数据之前,通过字典指定每列对应的数据类型,读入之后按照此类型显示数据。

>> dtypes = {
        'ip'            : 'uint32',
        'app'           : 'uint16',
        'device'        : 'uint16',
        'os'            : 'uint16',
        'channel'       : 'uint16',
        'is_attributed' : 'uint8',
        }
>> train = pd.read_csv('../input/train_sample.csv', dtype=dtypes)

通过改变数据类型减少空间的案例。修改DataFrame d中的一列Sctcd,注意到该列的数据都是1、2、0,而保存类型是object,果断改成uint8,通过df.info(memory_usage='deep')方法对比内存的使用情况。仅仅修改了一个列的类型,数据大小减小3MB。

>> d = pd.read_excel('xxx.xls')
>> d.info(memory_usage='deep')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 65002 entries, 0 to 65001
Data columns (total 14 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
...
 2   Sctcd    65002 non-null  object
...
 13  Eranb    60526 non-null  object
dtypes: object(14)
memory usage: 42.8 MB
>> d['Sctcd'] = d['Sctcd'].astype('uint8')
>> d.info(memory_usage='deep')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 65000 entries, 2 to 65001
Data columns (total 14 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
...
 2   Sctcd    65000 non-null  uint8 
...
 13  Eranb    60524 non-null  object
dtypes: object(13), uint8(1)
memory usage: 39.3 MB

一个特殊而高效的案例是当某一列的值只有有限个,不管是int还是string格式,且该列unque值远小于列的长度,可以将该列转变为category类,将节省大量空间。这么做当然也有代价,比如转换成category类的数据将无法做max/min等运算,由数字转换成的category也不能进行数值运算。这种转换对内存的节省效果显著,下面是对比。dcol只有两列,StkcdStknme,查看unique的个数与总长度,显示unique远小于总长度,分别转换为category类型,内存节省超过90%!

>> dcol.info(memory_usage='deep')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 65002 entries, 0 to 65001
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   Stkcd   65002 non-null  object
 1   Stknme  65002 non-null  object
dtypes: object(2)
memory usage: 9.5 MB
>> dcol['Stkcd'] = dcol['Stkcd'].astype('category')
>> dcol['Stknme'] = dcol['Stknme'].astype('category')
>> dcol.info(memory_usage='deep')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 65002 entries, 0 to 65001
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype   
---  ------  --------------  -----   
 0   Stkcd   65002 non-null  category
 1   Stknme  65002 non-null  category
dtypes: category(2)
memory usage: 780.0 KB

分块读取大文件.csv

通过Pandas的read_csv方法中的chunksize选项指定读取的块大小,并迭代地对读取的块做运算。

>> chunks = 10000
>> data = pd.read_excel('xxx.xls', chunksize=chunks)
>> for chunk in data:   
       # process chunk
       pass

清除不用的变量并回收内存

>> tmp = df.DataFrame(...)
>> del tmp
>> import gc
>> gc.collect()
16

Reference

1 https冒号//www点dataquest点io/blog/pandas-big-data/
2 CSDN - python 处理大量数据_如何用python处理大量数据
2 How to Work with BIG Datasets on 16G RAM (+Dask), on kaggle

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容