• 当然对于处理大数据集,类似spark之类的专业处理工具是大家的首选,但是pandas优秀的特性和简单明了的语法能极大提升数据分析的效率,因此我需要考虑如何对数据优化,使得我们能在pandas上完成更大数据量的数据分析...

    翻译自这篇文章

    当我们需要处理大数据时,如果不对数据做任何处理,可能会带来内存占用过大和运行过慢的风险。

    当然对于处理大数据集,类似spark之类的专业处理工具是大家的首选,但是pandas优秀的特性和简单明了的语法能极大提升数据分析的效率,因此我需要考虑如何对数据优化,使得我们能在pandas上完成更大数据量的数据分析工作。

    在用pandas进行数据分析时,减少内存占用简单来说就是选择合适的数据类型。

    我们用棒球比赛日志数据来作为我们的例子。

    import pandas as pd
    gl = pd.read_csv("game_logs.csv")#读数据
    
    gl.info(memory_usage = 'deep')#数据集的一些信息和内存占用

    我们先了解下pandas内部储存Dataframe的机制。
    pandas将列聚合成一个个的blocks,block内都是相同类型的数据。blocks不会存储列名,只会储存dataframe列中的实际的值。内部的BlockManager class会将row和column的indexes与它们的值一一映射起来。当我们选择,编辑,删除值的时候,dataframe类会和BlockManager类交互,将我们的请求转换成相应的函数和方法调用。

    pandas中,有一个叫pandas.core.internals模块,这里有许多的class,每个数据类型都对应了一个特殊的class。例如Pandas用ObjectBlock类来表示包含了存储string类型数据的列的block。对于包含存储数值数据比如说整型和浮点型数据的block,pandas将他们合并在一起,并用Numpy ndarray来存储。

    由于每个数据类型在pandas中的都是分别存储的。我们可以看下每种数据类型平均需要用多少的内存空间。

    for dtype in ['float', 'int', 'object]:
        selected_dtype = gl.select_dtypes(include = [dtypes])
        mean_usage_b = selected.dtype.memory_usage(deep = True)
        mean_usage_mb = mean_usage_b / 1024 ** 2
        print("Average memory usage for {} columns: {:03.2f} MB".format(dtype, mean_usage_mb))

    正如我们之前提到的,pandas用Numpy ndarrays来表示数值型数据,并且将他们存放在连续的内存单元中。这样的存储模型能消耗更小的空间资源,并且能使我们的访问更加迅速。

    许多的pandas中的类有许多的子类。例如float类型有flloat16,float32和float64这些子类。使用的内存依次上升。

    我们可以用numy.iinfo类来观察每个子类的最大值和最小值。例如

    import numpy as np
    int_types = ['uint8', 'int8', 'int16']
    for it in int_types:
        print(np.iinfo(it))

    这里uint代表了无符号整型,int代表了带符号整型。两种子类的存储空间都是相同的。

    我们可以再看下数据类型转换后的内存变化情况。

    def mem_usage(pandas_obj):
        if isinstance(pandas_obj, pd.DataFrame):
            usage_b = pandas_obj.memory_usage(deep = True).sum()
        else:
            usage_b = pandas_obj.memory_usage(deep = True)
        usage_mb = usage_b / 1024 ** 2
        return "{:03.2f} MB".format(usage_mb)
    
    gl_int = gl.select_dtypes(include = ['int'])
    converted_int = gl_int.apply(pd.to_numeric, downcast = 'unsigned')
    
    print(mem_usage(go_int))
    print(mem_usage(converted_int))
    
    compare_ints = pd.concat([gl_int.dtypes, converted_int.dtypes], axis = 1)
    compare_ints.columnns = ['before', 'after']
    compare_ints.apply(pd.Series.value_counts)

    我们对float类型的数据也做同样的处理。最后看下整个数据集内存减少了多少。

    optimized_gl = gl.copy()
    
    optimized_gl[converted_int.columns] = converted_int
    optimized_gl[converted_float.columns] = converted_float
    
    print(mem_usage(gl))
    print(mem_usage(optimized_gl))

    我们发现,仅仅对数值型数据做类型变换不能大幅度的减少整个数据集的内存占用情况。因此我们需要对最耗内存的,也就是object类型的数据进行优化。

    pandas中的object类型的数据表示数据是Python string类型的,部分原因是因为在Numpy中缺少对缺失string值的支持机制,因为Python语言的原因,它没有一个好的对值的内存管理的机制。

    这样的限制导致了strings被存储在非连续的内存单元当中,每一个元素实际上是一个包含了值的实际内存地址的指针。

    from sys import getsizeof
    
    s1 = "working out"
    s2 = "memory usage for"
    s3 = "strings in python is fun!"
    s4 = "strings in python is fun!" 
    
    for s in [s1, s2, s3, s4]:
        print(getsizeof(s))

    我们用categgory类型来对object类型的数据做优化。

    dow = gl_ob.day_of_week
    print(dow.head())
    
    dow_cat = dow.astype("category")
    print(dow_cat.head())

    如果运行,我们将会看到这样的操作的确节省了非常多的内存。

    展开全文
  • 易上手, 文档丰富的Pandas 已经成为时下最火的数据处理库。此外,Pandas数据处理能力也一流。 其实无论你使用什么库,大量的数据处理起来往往回遇到新的挑战。 数据处理时,往往会遇到没有足够内存(RAM)这个硬件...

    在这里插入图片描述

    原文链接:3 simple ways to handle large data with
    Pandas

    作者 | George Seif
    译者 | jojoa

    易上手, 文档丰富的Pandas 已经成为时下最火的数据处理库。此外,Pandas数据处理能力也一流。

    其实无论你使用什么库,大量的数据处理起来往往回遇到新的挑战。
    数据处理时,往往会遇到没有足够内存(RAM)这个硬件问题。 企业往往需要能够存够数百, 乃至数千 的GB 数据。
    即便你的计算机恰好有足够的内存来存储这些数据, 但是读取数据到硬盘依旧非常耗时。
    别担心! Pandas 数据库会帮我们摆脱这种困境。 这篇文章包含3种方法来减少数据大小,并且加快数据读取速度。 我用这些方法,把超过100GB 的数据, 压缩到了64GB 甚至32GB 的内存大小。

    快来看看这三个妙招吧。

    数据分块

    csv 格式是一种易储存, 易更改并且用户易读取的格式。 pandas 有read_csv ()方法来上传数据,存储为CSV 格式。当遇到CSV 文件过大,导致内存不足的问题该怎么办呢?试试强大的pandas 工具吧!我们先把整个文件拆分成小块。这里,我们把拆分的小块称为chunk。

    一个chunk 就是我们数据的一个小组。 Chunk 的大小主要依据我们内存的大小,自行决定。

    过程如下:

    1.读取一块数据。
    2.分析数据。
    3.保存该块数据的分析结果。
    4.重复1-3步骤,直到所有chunk 分析完毕。
    5.把所有的chunk 合并在一起。

    我们可以通过read_csv()方法Chunksize来完成上述步骤。 Chunksize是指pandas 一次能读取到多少行csv文件。这个当然也是建立在RAM 内存容量的基础上。
    假如我们认为数据呈现高斯分布时, 我们可以在一个chunk 上, 进行数据处理和视觉化, 这样会提高准确率。

    当数据稍微复杂时, 例如呈现泊松分布时, 我们最好能一块块筛选,然后把每一小块整合在一起。 然后再进行分析。很多时候, 我们往往删除太多的不相关列,或者删除有值行。 我们可以在每个chunk 上,删除不相关数据, 然后再把数据整合在一起,最后再进行数据分析。

    代码如下:

    在这里插入图片描述
    删除数据

    有时候, 我们一眼就能看到需要分析的列。事实上, 通常名字,账号等列,我们是不做分析的。

    读取数据前, 先跳过这些无用的列,可以帮我们节省很多内存。 Pandas 可以允许我们选择想要读取的列。

    在这里插入图片描述
    把包含无用信息的列删除掉, 往往给我们节省了大量内存。

    此外,我们还可以把有缺失值的行,或者是包含“NA” 的行删除掉。 通过dropna()方法可以实现:

    在这里插入图片描述
    有几个非常有用的参数,可以传给dropna():

    • how: 可选项:“any”(该行的任意一列如果出现”NA”, 删除该行)
    • “all” (只有某行所有数数据全部是”NA” 时才删除)
    • thresh: 设定某行最多包含多少个NA 时,才进行删除
    • subset: 选定某个子集,进行NA 查找

    可以通过这些参数, 尤其是thresh 和 subset 两个参数可以决定某行是否被删除掉。

    Pandas 在读取信息的时候,无法删除列。但是我们可以在每个chunk 上,进行上述操作。

    为列设定不同的数据类型

    数据科学家新手往往不会对数据类型考虑太多。 当处理数据越来越多时, 就非常有必要考虑数据类型了。

    行业常用的解决方法是从数据文件中,读取数据, 然后一列列设置数据类型。 但当数据量非常大时, 我们往往担心内存空间不够用。

    在CSV 文件中,例如某列是浮点数, 它往往会占据更多的存储空间。 例如, 当我们下载数据来预测股票信息时, 价格往往以32位浮点数形式存储。

    但是,我们真的需要32位浮点数码? 大多数情况下, 股票价格以小数点后保留两位数据进行交易。 即便我们想看到更精确的数据, 16位浮点数已经足够了。

    我们往往会在读取数据的时候, 设置数据类型,而不是保留数据原类型。 那样的话,会浪费掉部分内存。

    通过read_csv() 中设置dtype参数来完成数据类型设置。还可以设置字典类型,设置该列是键, 设置某列是字典的值。

    请看下面的pandas 例子:

    在这里插入图片描述
    文章到这里结束了! 希望上述三个方法可以帮你节省时间和内存。

    展开全文
  • 一般来说,用pandas处理小于100兆的数据,性能不是问题。当用pandas来处理100兆至几个G的数据时,将会比较耗时,同时会导致程序因内存不足而运行失败。 当然,像Spark这类的工具能够胜任处理100G至几个T的大数据集,...

    一般来说,用pandas处理小于100兆的数据,性能不是问题。当用pandas来处理100兆至几个G的数据时,将会比较耗时,同时会导致程序因内存不足而运行失败。

    当然,像Spark这类的工具能够胜任处理100G至几个T的大数据集,但要想充分发挥这些工具的优势,通常需要比较贵的硬件设备。而且,这些工具不像pandas那样具有丰富的进行高质量数据清洗、探索和分析的特性。对于中等规模的数据,我们的愿望是尽量让pandas继续发挥其优势,而不是换用其他工具。

    本文我们讨论pandas的内存使用,展示怎样简单地为数据列选择合适的数据类型,就能够减少dataframe近90%的内存占用。

    处理棒球比赛记录数据

    我们将处理130年的棒球甲级联赛的数据,数据源于

    Retrosheet(http://www.retrosheet.org/gamelogs/index.html)

    原始数据放在127个csv文件中,我们已经用csvkit

    (https://csvkit.readthedocs.io/en/1.0.2/)

    https://data.world/dataquest/mlb-game-logs

    我们从导入数据,并输出前5行开始:

    我们将一些重要的字段列在下面:

    • date- 比赛日期

    • v_name- 客队名

    • v_league- 客队联赛

    • h_name- 主队名

    • h_league- 主队联赛

    • v_score- 客队得分

    • h_score- 主队得分

    • v_line_score- 客队线得分, 如010000(10)00.

    • h_line_score- 主队线得分, 如010000(10)0X.

    • park_id- 主办场地的ID

    • attendance- 比赛出席人数

    我们可以用Dataframe.info()方法来获得我们dataframe的一些高level信息,譬如数据量、数据类型和内存使用量。

    这个方法默认情况下返回一个近似的内存使用量,现在我们设置参数memory_usage‘deep’来获得准确的内存使用量:

    我们可以看到它有171907行和161列。pandas已经为我们自动检测了数据类型,其中包括83列数值型数据和78列对象型数据。对象型数据列用于字符串或包含混合数据类型的列。

    由此我们可以进一步了解我们应该如何减少内存占用,下面我们来看一看pandas如何在内存中存储数据。

    Dataframe对象的内部表示

    在底层,pandas会按照数据类型将列分组形成数据块(blocks)。下图所示为pandas如何存储我们数据表的前十二列:

    可以注意到,这些数据块没有保持对列名的引用,这是由于为了存储dataframe中的真实数据,这些数据块都经过了优化。有个BlockManager类

    会用于保持行列索引与真实数据块的映射关系。他扮演一个API,提供对底层数据的访问。每当我们查询、编辑或删除数据时,dataframe类会利用BlockManager类接口将我们的请求转换为函数和方法的调用。

    每种数据类型在pandas.core.internals模块中都有一个特定的类。pandas使用ObjectBlock类来表示包含字符串列的数据块,用FloatBlock类来表示包含浮点型列的数据块。对于包含数值型数据(比如整型和浮点型)的数据块,pandas会合并这些列,并把它们存储为一个Numpy数组(ndarray)。Numpy数组是在C数组的基础上创建的,其值在内存中是连续存储的。基于这种存储机制,对其切片的访问是相当快的。

    由于不同类型的数据是分开存放的,我们将检查不同数据类型的内存使用情况,我们先看看各数据类型的平均内存使用量:

    由于不同类型的数据是分开存放的,我们将检查不同数据类型的内存使用情况,我们先看看各数据类型的平均内存使用量:

    我们可以看到内存使用最多的是78个object列,我们待会再来看它们,我们先来看看我们能否提高数值型列的内存使用效率

    选理解子类(Subtypes)

    刚才我们提到,pandas在底层将数值型数据表示成Numpy数组,并在内存中连续存储。这种存储方式消耗较少的空间,并允许我们较快速地访问数据。由于pandas使用相同数量的字节来表示同一类型的每一个值,并且numpy数组存储了这些值的数量,所以pandas能够快速准确地返回数值型列所消耗的字节量。

    pandas中的许多数据类型具有多个子类型,它们可以使用较少的字节去表示不同数据,比如,float型就有float16float32float64这些子类型。这些类型名称的数字部分表明了这种类型使用了多少比特来表示数据,比如刚才列出的子类型分别使用了2、4、8个字节。下面这张表列出了pandas中常用类型的子类型:

    一个int8类型的数据使用1个字节(8位比特)存储一个值,可以表示256(2^8)个二进制数值。这意味着我们可以用这种子类型去表示从-128到127(包括0)的数值。

    我们可以用numpy.iinfo类来确认每一个整型子类型的最小和最大值,如下

    这里我们还可以看到uint(无符号整型)和int(有符号整型)的区别。两者都占用相同的内存存储量,但无符号整型由于只存正数,所以可以更高效的存储只含正数的列。

    用子类型优化数值型列

    我们可以用函数pd.to_numeric()来对数值型进行向下类型转换。我们用DataFrame.select_dtypes来只选择整型列,然后我们优化这种类型,并比较内存使用量。

    我们看到内存用量从7.9兆下降到1.5兆,降幅达80%。这对我们原始dataframe的影响有限,这是由于它只包含很少的整型列。

    同理,我们再对浮点型列进行相应处理:

    我们可以看到所有的浮点型列都从float64转换为float32,内存用量减少50%。

    我们再创建一个原始dataframe的副本,将其数值列赋值为优化后的类型,再看看内存用量的整体优化效果。

    可以看到通过我们显著缩减数值型列的内存用量,我们的dataframe的整体内存用量减少了7%。余下的大部分优化将针对object类型进行

    在这之前,我们先来研究下与数值型相比,pandas如何存储字符串。

    选对比数值与字符的储存

    object类型用来表示用到了Python字符串对象的值,有一部分原因是Numpy缺少对缺失字符串值的支持。因为Python是一种高层、解析型语言,它没有提供很好的对内存中数据如何存储的细粒度控制。

    这一限制导致了字符串以一种碎片化方式进行存储,消耗更多的内存,并且访问速度低下。在object列中的每一个元素实际上都是存放内存中真实数据位置的指针。

    下图对比展示了数值型数据怎样以Numpy数据类型存储,和字符串怎样以Python内置类型进行存储的。

    图示来源并改编自Why Python Is Slow

    你可能注意到上文表中提到object类型数据使用可变(variable)大小的内存。由于一个指针占用1字节,因此每一个字符串占用的内存量与它在Python中单独存储所占用的内存量相等。我们用sys.getsizeof()来证明这一点,先来看看在Python单独存储字符串,再来看看使用pandas的series的情况。

    你可以看到这些字符串的大小在pandas的series中与在Python的单独字符串中是一样的。

    选用类别(categoricalas)类型优化object类型

    Pandas在0.15版本中引入类别类型。category类型在底层使用整型数值来表示该列的值,而不是用原值。Pandas用一个字典来构建这些整型数据到原数据的映射关系。当一列只包含有限种值时,这种设计是很不错的。当我们把一列转换成category类型时,pandas会用一种最省空间的int子类型去表示这一列中所有的唯一值。

    为了介绍我们何处会用到这种类型去减少内存消耗,让我们来看看我们数据中每一个object类型列中的唯一值个数。

    可以看到在我们包含了近172000场比赛的数据集中,很多列只包含了少数几个唯一值。

    我们先选择其中一个object列,开看看将其转换成类别类型会发生什么。这里我们选用第二列:day_of_week

    我们从上表中可以看到,它只包含了7个唯一值。我们用.astype()方法将其转换为类别类型。

    可以看到,虽然列的类型改变了,但数据看上去好像没什么变化。我们来看看底层发生了什么。

    下面的代码中,我们用Series.cat.codes属性来返回category类型用以表示每个值的整型数字。

    可以看到,每一个值都被赋值为一个整数,而且这一列在底层是int8类型。这一列没有任何缺失数据,但是如果有,category子类型会将缺失数据设为-1。

    最后,我们来看看这一列在转换为category类型前后的内存使用量。

    存用量从9.8兆降到0.16兆,近乎98%的降幅!注意这一特殊列可能代表了我们一个极好的例子——一个包含近172000个数据的列只有7个唯一值。

    这样的话,我们把所有这种类型的列都转换成类别类型应该会很不错,但这里面也要权衡利弊。首要问题是转变为类别类型会丧失数值计算能力,在将类别类型转换成真实的数值类型前,我们不能对category列做算术运算,也不能使用诸如Series.min()Series.max()等方法。

    对于唯一值数量少于50%的object列,我们应该坚持首先使用category类型。如果某一列全都是唯一值,category类型将会占用更多内存。这是因为这样做不仅要存储全部的原始字符串数据,还要存储整型类别标识。有关category类型的更多限制,参看pandas文档。

    下面我们写一个循环,对每一个object列进行迭代,检查其唯一值是否少于50%,如果是,则转换成类别类型。

    更之前一样进行比较:

    这本例中,所有的object列都被转换成了category类型,但其他数据集就不一定了,所以你最好还是得使用刚才的检查过程。

    本例的亮点是内存用量从752.72兆降为51.667兆,降幅达93%。我们将其与我们dataframe的剩下部分合并,看看初始的861兆数据降到了多少。

    耶,看来我们的进展还不错!我们还有一招可以做优化,如果你记得我们刚才那张类型表,会发现我们数据集第一列还可以用datetime类型来表示。

    你可能还记得这一列之前是作为整型读入的,并优化成了uint32。因此,将其转换成datetime会占用原来两倍的内存,因为datetime类型是64位比特的。将其转换为datetime的意义在于它可以便于我们进行时间序列分析。

    转换使用pandas.to_datetime()函数,并使用format参数告之日期数据存储为YYYY-MM-DD格式。

    在数据读入的时候设定数据类型

    目前为止,我们探索了一些方法,用来减少现有dataframe的内存占用。通过首先读入dataframe,再对其一步步进行内存优化,我们可以更好地了解这些优化方法能节省多少内存。然而,正如我们之前谈到,我们通常没有足够的内存去表达数据集中的所有数据。如果不能在一开始就创建dataframe,我们怎样才能应用内存节省技术呢?

    幸运的是,我们可以在读入数据集的时候指定列的最优数据类型。pandas.read_csv()函数有一些参数可以做到这一点。dtype参数接受一个以列名(string型)为键字典、以Numpy类型对象为值的字典。

    首先,我们将每一列的目标类型存储在以列名为键的字典中,开始前先删除日期列,因为它需要分开单独处理。

    现在我们使用这个字典,同时传入一些处理日期的参数,让日期以正确的格式读入。

    通过对列的优化,我们是pandas的内存用量从861.6兆降到104.28兆,有效降低88%。

    分析棒球比赛

    现在我们有了优化后的数据,可以进行一些分析。我们先看看比赛日的分布情况。

    我们可以看到,1920年代之前,周日棒球赛很少是在周日的,随后半个世纪才逐渐增多。

    我们也看到最后50年的比赛日分布变化相对比较平稳。

    我们来看看比赛时长的逐年变化。

    看来棒球比赛时长从1940年代之后逐渐变长。

    总结

    我们学习了pandas如何存储不同的数据类型,并利用学到的知识将我们的pandas dataframe的内存用量降低了近90%,仅仅只用了一点简单的技巧:

    • 将数值型列降级到更高效的类型

    • 将字符串列转换为类别类型

    通过对列的优化,我们是pandas的内存用量从861.6兆降到104.28兆,有效降低88%。

    原文链接:https://www.dataquest.io/blog/pandas-big-data/

    展开全文
  • Python大数据处理方案

    2018-03-26 21:30:37
    Mysql SQLyog导入导出csv文件SQLyog 导出表中数据存为csv文件1. 选择数据库表 --> 右击属性 --> 备份/导出 --> 导出表数据作为 --> 选择cvs --&... 选择下面的“更改” --&...

    Mysql SQLyog导入导出csv文件

    SQLyog 导出表中数据存为csv文件

    1.    选择数据库表 --> 右击属性 --> 备份/导出 --> 导出表数据作为 --> 选择cvs --> 选择下面的“更改” --> 字段 --> 可变长度--> 字段终止与 -->输入逗号,(这是重点,否则导出的csv文件内容都在一列中,而不是分字段分列)
    下面两个选项框取消。


    2.导出csv文件后,使用UE编辑器或者记事本打开,另存为,选择编码为utf-8格式,保存。

    3.打开csv文件,这样中文为正确的显示,如果不转码保存的话,为中文乱码。

    SQLyog 将csv文件数据导入mysql表中

    1.      将数据文件存为csv文件,保存的时候选择逗号(或\t)作为分隔符;

    2.    选择数据库表 --> 导入 --> 导入本地可使用的CSV数据 --> 从文件导入,选择刚刚的csv文件,导入完成。

     

     

    2.    选择cvs --> 选择下面的“更改” --> 字段 --> 可变长度--> 字段终止与 -->输入逗号,(这是重点,否则导入的csv文件内容都在一列中,而不是分字段分列)
    下面两个选项框取消。

     http://www.cnblogs.com/DswCnblog/p/5970873.html



    用Python Pandas处理亿级数据

    在数据分析领域,最热门的莫过于Python和R语言,此前有一篇文章《别老扯什么Hadoop了,你的数据根本不够大》指出:只有在超过5TB数据量的规模下,Hadoop才是一个合理的技术选择。这次拿到近亿条日志数据,千万级数据已经是关系型数据库的查询分析瓶颈,之前使用过Hadoop对大量文本进行分类,这次决定采用Python来处理数据:

    • 硬件环境
        • CPU:3.5 GHz Intel Core i7
        • 内存:32 GB HDDR 3 1600 MHz
        • 硬盘:3 TB Fusion Drive
    • 数据分析工具
        • Python:2.7.6
        • Pandas:0.15.0
        • IPython notebook:2.0.0

    源数据如下表所示:

     TableSizeDesc
    ServiceLogs98,706,832 rows x 14 columns8.77 GB交易日志数据,每个交易会话可以有多条交易
    ServiceCodes286 rows × 8 columns20 KB交易分类的字典表

    数据读取

    启动IPython notebook,加载pylab环境:

    Pandas提供了IO工具可以将大文件分块读取,测试了一下性能,完整加载9800万条数据也只需要263秒左右,还是相当不错了。

     1百万条1千万条1亿条
    ServiceLogs1 s17 s263 s

    使用不同分块大小来读取再调用 pandas.concat 连接DataFrame,chunkSize设置在1000万条左右速度优化比较明显。

    下面是统计数据,Read Time是数据读取时间,Total Time是读取和Pandas进行concat操作的时间,根据数据总量来看,对5~50个DataFrame对象进行合并,性能表现比较好。

    Chunk SizeRead Time (s)Total Time (s)Performance
    100,000224.418173261.358521 
    200,000232.076794256.674154 
    1,000,000213.128481234.934142√ √
    2,000,000208.410618230.006299√ √ √
    5,000,000209.460829230.939319√ √ √
    10,000,000207.082081228.135672√ √ √ √
    20,000,000209.628596230.775713√ √ √
    50,000,000222.910643242.405967 
    100,000,000263.574246263.574246 

    屏幕快照 2015-02-17 下午2.05.48

    如果使用Spark提供的Python Shell,同样编写Pandas加载数据,时间会短25秒左右,看来Spark对Python的内存使用都有优化。

    数据清洗

    Pandas提供了 DataFrame.describe 方法查看数据摘要,包括数据查看(默认共输出首尾60行数据)和行列统计。由于源数据通常包含一些空值甚至空列,会影响数据分析的时间和效率,在预览了数据摘要后,需要对这些无效数据进行处理。

    首先调用 DataFrame.isnull() 方法查看数据表中哪些为空值,与它相反的方法是 DataFrame.notnull() ,Pandas会将表中所有数据进行null计算,以True/False作为结果进行填充,如下图所示:

    屏幕快照 2015-02-16 下午11.21.29

    Pandas的非空计算速度很快,9800万数据也只需要28.7秒。得到初步信息之后,可以对表中空列进行移除操作。尝试了按列名依次计算获取非空列,和 DataFrame.dropna() 两种方式,时间分别为367.0秒和345.3秒,但检查时发现 dropna() 之后所有的行都没有了,查了Pandas手册,原来不加参数的情况下, dropna() 会移除所有包含空值的行。如果只想移除全部为空值的列,需要加上 axis 和 how 两个参数:

    共移除了14列中的6列,时间也只消耗了85.9秒。

    接下来是处理剩余行中的空值,经过测试,在 DataFrame.replace() 中使用空字符串,要比默认的空值NaN节省一些空间;但对整个CSV文件来说,空列只是多存了一个“,”,所以移除的9800万 x 6列也只省下了200M的空间。进一步的数据清洗还是在移除无用数据和合并上。

    对数据列的丢弃,除无效值和需求规定之外,一些表自身的冗余列也需要在这个环节清理,比如说表中的流水号是某两个字段拼接、类型描述等,通过对这些数据的丢弃,新的数据文件大小为4.73GB,足足减少了4.04G!

    数据处理

    使用 DataFrame.dtypes 可以查看每列的数据类型,Pandas默认可以读出int和float64,其它的都处理为object,需要转换格式的一般为日期时间。DataFrame.astype() 方法可对整个DataFrame或某一列进行数据格式转换,支持Python和NumPy的数据类型。

    对数据聚合,我测试了 DataFrame.groupby 和 DataFrame.pivot_table 以及 pandas.merge ,groupby 9800万行 x 3列的时间为99秒,连接表为26秒,生成透视表的速度更快,仅需5秒。

    根据透视表生成的交易/查询比例饼图:

    屏幕快照 2015-02-17 上午12.00.09

    将日志时间加入透视表并输出每天的交易/查询比例图:

    屏幕快照 2015-02-17 下午2.27.05

    除此之外,Pandas提供的DataFrame查询统计功能速度表现也非常优秀,7秒以内就可以查询生成所有类型为交易的数据子表:

    该子表的大小为 [10250666 rows x 5 columns]。在此已经完成了数据处理的一些基本场景。实验结果足以说明,在非“>5TB”数据的情况下,Python的表现已经能让擅长使用统计分析语言的数据分析师游刃有余。

     


    展开全文
  • pandas处理大数据———减少90%内存消耗的小贴士 一般来说,用pandas处理小于100兆的数据,性能不是问题。当用pandas来处理100兆至几个G的数据时,将会比较耗时,同时会导致程序因内存不足而运行失败。 当然,像...

    原文地址https://www.dataquest.io/blog/pandas-big-data/

    一般来说,用pandas处理小于100兆的数据,性能不是问题。当用pandas来处理100兆至几个G的数据时,将会比较耗时,同时会导致程序因内存不足而运行失败。

    当然,像Spark这类的工具能够胜任处理100G至几个T的大数据集,但要想充分发挥这些工具的优势,通常需要比较贵的硬件设备。而且,这些工具不像pandas那样具有丰富的进行高质量数据清洗、探索和分析的特性。对于中等规模的数据,我们的愿望是尽量让pandas继续发挥其优势,而不是换用其他工具。

    本文我们讨论pandas的内存使用,展示怎样简单地为数据列选择合适的数据类型,就能够减少dataframe近90%的内存占用。

    处理棒球比赛记录数据

    我们将处理130年的棒球甲级联赛的数据,数据源于Retrosheet

    原始数据放在127个csv文件中,我们已经用csvkit将其合并,并添加了表头。如果你想下载我们版本的数据用来运行本文的程序,我们提供了下载地址

    我们从导入数据,并输出前5行开始:

    import pandas as pd
    
    gl = pd.read_csv('game_logs.csv')
    gl.head()
      date number_of_game day_of_week v_name v_league v_game_number h_name
    0 18710504 0 Thu CL1 na 1 FW1
    1 18710505 0 Fri BS1 na 1 WS3
    2 18710506 0 Sat CL1 na 2 RC1
    3 18710508 0 Mon CL1 na 3 CH1
    4 18710509 0 Tue BS1 na 2 TRO

    我们将一些重要的字段列在下面:

    • date - 比赛日期
    • v_name - 客队名
    • v_league - 客队联赛
    • h_name - 主队名
    • h_league - 主队联赛
    • v_score - 客队得分
    • h_score - 主队得分
    • v_line_score - 客队线得分, 如010000(10)00.
    • h_line_score- 主队线得分, 如010000(10)0X.
    • park_id - 主办场地的ID
    • attendance- 比赛出席人数

    我们可以用Dataframe.info()方法来获得我们dataframe的一些高level信息,譬如数据量、数据类型和内存使用量。

    这个方法默认情况下返回一个近似的内存使用量,现在我们设置参数memory_usage'deep'来获得准确的内存使用量:

    gl.info(memory_usage='deep')
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 171907 entries, 0 to 171906
    Columns: 161 entries, date to acquisition_info
    dtypes: float64(77), int64(6), object(78)
    memory usage: 861.6 MB
    

    我们可以看到它有171907行和161列。pandas已经为我们自动检测了数据类型,其中包括83列数值型数据和78列对象型数据。对象型数据列用于字符串或包含混合数据类型的列。

    由此我们可以进一步了解我们应该如何减少内存占用,下面我们来看一看pandas如何在内存中存储数据。

    Dataframe对象的内部表示

    在底层,pandas会按照数据类型将列分组形成数据块(blocks)。下图所示为pandas如何存储我们数据表的前十二列:

    可以注意到,这些数据块没有保持对列名的引用,这是由于为了存储dataframe中的真实数据,这些数据块都经过了优化。有个BlockManager类会用于保持行列索引与真实数据块的映射关系。他扮演一个API,提供对底层数据的访问。每当我们查询、编辑或删除数据时,dataframe类会利用BlockManager类接口将我们的请求转换为函数和方法的调用。

    每种数据类型在pandas.core.internals模块中都有一个特定的类。pandas使用ObjectBlock类来表示包含字符串列的数据块,用FloatBlock类来表示包含浮点型列的数据块。对于包含数值型数据(比如整型和浮点型)的数据块,pandas会合并这些列,并把它们存储为一个Numpy数组(ndarray)。Numpy数组是在C数组的基础上创建的,其值在内存中是连续存储的。基于这种存储机制,对其切片的访问是相当快的。

    由于不同类型的数据是分开存放的,我们将检查不同数据类型的内存使用情况,我们先看看各数据类型的平均内存使用量:

    for dtype in ['float','int','object']:
        selected_dtype = gl.select_dtypes(include=[dtype])
        mean_usage_b = selected_dtype.memory_usage(deep=True).mean()
        mean_usage_mb = mean_usage_b / 1024 ** 2
        print("Average memory usage for {} columns: {:03.2f} MB".format(dtype,mean_usage_mb))
    Average memory usage for float columns: 1.29 MB
    Average memory usage for int columns: 1.12 MB
    Average memory usage for object columns: 9.53 MB
    

    我们可以看到内存使用最多的是78个object列,我们待会再来看它们,我们先来看看我们能否提高数值型列的内存使用效率。

    理解子类型(Subtypes)

    刚才我们提到,pandas在底层将数值型数据表示成Numpy数组,并在内存中连续存储。这种存储方式消耗较少的空间,并允许我们较快速地访问数据。由于pandas使用相同数量的字节来表示同一类型的每一个值,并且numpy数组存储了这些值的数量,所以pandas能够快速准确地返回数值型列所消耗的字节量。

    pandas中的许多数据类型具有多个子类型,它们可以使用较少的字节去表示不同数据,比如,float型就有float16float32float64这些子类型。这些类型名称的数字部分表明了这种类型使用了多少比特来表示数据,比如刚才列出的子类型分别使用了2、4、8个字节。下面这张表列出了pandas中常用类型的子类型:

    memory usage float int uint datetime bool object
    1 bytes int8 uint8 bool
    2 bytes float16 int16 uint16
    4 bytes float32 int32 uint32
    8 bytes float64 int64 uint64 datetime64
    variable object

    一个int8类型的数据使用1个字节(8位比特)存储一个值,可以表示256(2^8)个二进制数值。这意味着我们可以用这种子类型去表示从-128到127(包括0)的数值。

    我们可以用numpy.iinfo类来确认每一个整型子类型的最小和最大值,如下:

    import numpy as np
    int_types = ["uint8", "int8", "int16"]
    for it in int_types:
        print(np.iinfo(it))
    Machine parameters for uint8
    -----------------------------------------------------
    min = 0
    max = 255
    -----------------------------------------------------
    
    Machine parameters for int8
    -----------------------------------------------------
    min = -128
    max = 127
    -----------------------------------------------------
    
    Machine parameters for int16
    -----------------------------------------------------
    min = -32768
    max = 32767
    -----------------------------------------------------
    

    这里我们还可以看到uint(无符号整型)和int(有符号整型)的区别。两者都占用相同的内存存储量,但无符号整型由于只存正数,所以可以更高效的存储只含正数的列。

    用子类型优化数值型列

    我们可以用函数pd.to_numeric()来对数值型进行向下类型转换。我们用DataFrame.select_dtypes来只选择整型列,然后我们优化这种类型,并比较内存使用量。

    # We're going to be calculating memory usage a lot,
    # so we'll create a function to save us some time!
    
    def mem_usage(pandas_obj):
        if isinstance(pandas_obj,pd.DataFrame):
            usage_b = pandas_obj.memory_usage(deep=True).sum()
        else: # we assume if not a df it's a series
            usage_b = pandas_obj.memory_usage(deep=True)
        usage_mb = usage_b / 1024 ** 2 # convert bytes to megabytes
        return "{:03.2f} MB".format(usage_mb)
    
    gl_int = gl.select_dtypes(include=['int'])
    converted_int = gl_int.apply(pd.to_numeric,downcast='unsigned')
    
    print(mem_usage(gl_int))
    print(mem_usage(converted_int))
    
    compare_ints = pd.concat([gl_int.dtypes,converted_int.dtypes],axis=1)
    compare_ints.columns = ['before','after']
    compare_ints.apply(pd.Series.value_counts)
    7.87 MB
    1.48 MB
    
      before after
    uint8 NaN 5.0
    uint32 NaN 1.0
    int64 6.0 NaN

    我们看到内存用量从7.9兆下降到1.5兆,降幅达80%。这对我们原始dataframe的影响有限,这是由于它只包含很少的整型列。

    同理,我们再对浮点型列进行相应处理:

    gl_float = gl.select_dtypes(include=['float'])
    converted_float = gl_float.apply(pd.to_numeric,downcast='float')
    
    print(mem_usage(gl_float))
    print(mem_usage(converted_float))
    
    compare_floats = pd.concat([gl_float.dtypes,converted_float.dtypes],axis=1)
    compare_floats.columns = ['before','after']
    compare_floats.apply(pd.Series.value_counts)
    100.99 MB
    50.49 MB
    
      before after
    float32 NaN 77.0
    float64 77.0 NaN

    我们可以看到所有的浮点型列都从float64转换为float32,内存用量减少50%。

    我们再创建一个原始dataframe的副本,将其数值列赋值为优化后的类型,再看看内存用量的整体优化效果。

    optimized_gl = gl.copy()
    
    optimized_gl[converted_int.columns] = converted_int
    optimized_gl[converted_float.columns] = converted_float
    
    print(mem_usage(gl))
    print(mem_usage(optimized_gl))
    861.57 MB
    804.69 MB
    

    可以看到通过我们显著缩减数值型列的内存用量,我们的dataframe的整体内存用量减少了7%。余下的大部分优化将针对object类型进行。

    在这之前,我们先来研究下与数值型相比,pandas如何存储字符串。

    对比数值与字符的存储

    object类型用来表示用到了Python字符串对象的值,有一部分原因是Numpy缺少对缺失字符串值的支持。因为Python是一种高层、解析型语言,它没有提供很好的对内存中数据如何存储的细粒度控制。

    这一限制导致了字符串以一种碎片化方式进行存储,消耗更多的内存,并且访问速度低下。在object列中的每一个元素实际上都是存放内存中真实数据位置的指针。

    下图对比展示了数值型数据怎样以Numpy数据类型存储,和字符串怎样以Python内置类型进行存储的。


    图示来源并改编自Why Python Is Slow

    你可能注意到上文表中提到object类型数据使用可变(variable)大小的内存。由于一个指针占用1字节,因此每一个字符串占用的内存量与它在Python中单独存储所占用的内存量相等。我们用sys.getsizeof()来证明这一点,先来看看在Python单独存储字符串,再来看看使用pandas的series的情况。

    from sys import getsizeof
    
    s1 = 'working out'
    s2 = 'memory usage for'
    s3 = 'strings in python is fun!'
    s4 = 'strings in python is fun!'
    
    for s in [s1, s2, s3, s4]:
        print(getsizeof(s))
    60
    65
    74
    74
    
    obj_series = pd.Series(['working out',
                              'memory usage for',
                              'strings in python is fun!',
                              'strings in python is fun!'])
    obj_series.apply(getsizeof)
    0    60
    1    65
    2    74
    3    74
    dtype: int64
    

    你可以看到这些字符串的大小在pandas的series中与在Python的单独字符串中是一样的。

    用类别(categoricals)类型优化object类型

    Pandas在0.15版本中引入类别类型。category类型在底层使用整型数值来表示该列的值,而不是用原值。Pandas用一个字典来构建这些整型数据到原数据的映射关系。当一列只包含有限种值时,这种设计是很不错的。当我们把一列转换成category类型时,pandas会用一种最省空间的int子类型去表示这一列中所有的唯一值。

    为了介绍我们何处会用到这种类型去减少内存消耗,让我们来看看我们数据中每一个object类型列中的唯一值个数。

    gl_obj = gl.select_dtypes(include=['object']).copy()
    gl_obj.describe()
      day_of_week v_name v_league h_name h_league day_night
    count 171907 171907 171907 171907 171907 140150
    unique 7 148 7 148 7 2
    top Sat CHN NL CHN NL D
    freq 28891 8870 88866 9024 88867 82724

    可以看到在我们包含了近172000场比赛的数据集中,很多列只包含了少数几个唯一值。

    我们先选择其中一个object列,开看看将其转换成类别类型会发生什么。这里我们选用第二列:day_of_week

    我们从上表中可以看到,它只包含了7个唯一值。我们用.astype()方法将其转换为类别类型。

    dow = gl_obj.day_of_week
    print(dow.head())
    
    dow_cat = dow.astype('category')
    print(dow_cat.head())
    0    Thu
    1    Fri
    2    Sat
    3    Mon
    4    Tue
    Name: day_of_week, dtype: object
    0    Thu
    1    Fri
    2    Sat
    3    Mon
    4    Tue
    Name: day_of_week, dtype: category
    Categories (7, object): [Fri, Mon, Sat, Sun, Thu, Tue, Wed]
    

    可以看到,虽然列的类型改变了,但数据看上去好像没什么变化。我们来看看底层发生了什么。

    下面的代码中,我们用Series.cat.codes属性来返回category类型用以表示每个值的整型数字。

    dow_cat.head().cat.codes
    0    4
    1    0
    2    2
    3    1
    4    5
    dtype: int8
    

    可以看到,每一个值都被赋值为一个整数,而且这一列在底层是int8类型。这一列没有任何缺失数据,但是如果有,category子类型会将缺失数据设为-1。

    最后,我们来看看这一列在转换为category类型前后的内存使用量。

    print(mem_usage(dow))
    print(mem_usage(dow_cat))
    9.84 MB
    0.16 MB
    

    内存用量从9.8兆降到0.16兆,近乎98%的降幅!注意这一特殊列可能代表了我们一个极好的例子——一个包含近172000个数据的列只有7个唯一值。

    这样的话,我们把所有这种类型的列都转换成类别类型应该会很不错,但这里面也要权衡利弊。首要问题是转变为类别类型会丧失数值计算能力,在将类别类型转换成真实的数值类型前,我们不能对category列做算术运算,也不能使用诸如Series.min()Series.max()等方法。

    对于唯一值数量少于50%的object列,我们应该坚持首先使用category类型。如果某一列全都是唯一值,category类型将会占用更多内存。这是因为这样做不仅要存储全部的原始字符串数据,还要存储整型类别标识。有关category类型的更多限制,参看pandas文档

    下面我们写一个循环,对每一个object列进行迭代,检查其唯一值是否少于50%,如果是,则转换成类别类型。

    converted_obj = pd.DataFrame()
    
    for col in gl_obj.columns:
        num_unique_values = len(gl_obj[col].unique())
        num_total_values = len(gl_obj[col])
        if num_unique_values / num_total_values < 0.5:
            converted_obj.loc[:,col] = gl_obj[col].astype('category')
        else:
            converted_obj.loc[:,col] = gl_obj[col]

    更之前一样进行比较:

    print(mem_usage(gl_obj))
    print(mem_usage(converted_obj))
    
    compare_obj = pd.concat([gl_obj.dtypes,converted_obj.dtypes],axis=1)
    compare_obj.columns = ['before','after']
    compare_obj.apply(pd.Series.value_counts)
    752.72 MB
    51.67 MB
    
      before after
    object 78.0 NaN
    category NaN 78.0

    这本例中,所有的object列都被转换成了category类型,但其他数据集就不一定了,所以你最好还是得使用刚才的检查过程。

    本例的亮点是内存用量从752.72兆降为51.667兆,降幅达93%。我们将其与我们dataframe的剩下部分合并,看看初始的861兆数据降到了多少。

    optimized_gl[converted_obj.columns] = converted_obj
    
    mem_usage(optimized_gl)
    '103.64 MB'
    

    耶,看来我们的进展还不错!我们还有一招可以做优化,如果你记得我们刚才那张类型表,会发现我们数据集第一列还可以用datetime类型来表示。

    date = optimized_gl.date
    print(mem_usage(date))
    date.head()
    0.66 MB
    0    18710504
    1    18710505
    2    18710506
    3    18710508
    4    18710509
    Name: date, dtype: uint32
    

    你可能还记得这一列之前是作为整型读入的,并优化成了uint32。因此,将其转换成datetime会占用原来两倍的内存,因为datetime类型是64位比特的。将其转换为datetime的意义在于它可以便于我们进行时间序列分析。

    转换使用pandas.to_datetime()函数,并使用format参数告之日期数据存储为YYYY-MM-DD格式。

    optimized_gl['date'] = pd.to_datetime(date,format='%Y%m%d')
    
    print(mem_usage(optimized_gl))
    optimized_gl.date.head()
    104.29 MB
    0   1871-05-04
    1   1871-05-05
    2   1871-05-06
    3   1871-05-08
    4   1871-05-09
    Name: date, dtype: datetime64[ns]
    

    在数据读入的时候设定数据类型

    目前为止,我们探索了一些方法,用来减少现有dataframe的内存占用。通过首先读入dataframe,再对其一步步进行内存优化,我们可以更好地了解这些优化方法能节省多少内存。然而,正如我们之前谈到,我们通常没有足够的内存去表达数据集中的所有数据。如果不能在一开始就创建dataframe,我们怎样才能应用内存节省技术呢?

    幸运的是,我们可以在读入数据集的时候指定列的最优数据类型。pandas.read_csv()函数有一些参数可以做到这一点。dtype参数接受一个以列名(string型)为键字典、以Numpy类型对象为值的字典。

    首先,我们将每一列的目标类型存储在以列名为键的字典中,开始前先删除日期列,因为它需要分开单独处理。

    dtypes = optimized_gl.drop('date',axis=1).dtypes
    
    dtypes_col = dtypes.index
    dtypes_type = [i.name for i in dtypes.values]
    
    column_types = dict(zip(dtypes_col, dtypes_type))
    
    # rather than print all 161 items, we'll
    # sample 10 key/value pairs from the dict
    # and print it nicely using prettyprint
    
    preview = first2pairs = {key:value for key,value in list(column_types.items())[:10]}
    import pprint
    pp = pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(preview)
    {   'acquisition_info': 'category',
        'h_caught_stealing': 'float32',
        'h_player_1_name': 'category',
        'h_player_9_name': 'category',
        'v_assists': 'float32',
        'v_first_catcher_interference': 'float32',
        'v_grounded_into_double': 'float32',
        'v_player_1_id': 'category',
        'v_player_3_id': 'category',
        'v_player_5_id': 'category'}
    

    现在我们使用这个字典,同时传入一些处理日期的参数,让日期以正确的格式读入。

    read_and_optimized = pd.read_csv('game_logs.csv',dtype=column_types,parse_dates=['date'],infer_datetime_format=True)
    
    print(mem_usage(read_and_optimized))
    read_and_optimized.head()
    104.28 MB
    
      date number_of_game day_of_week v_name v_league v_game_number h_name
    0 1871-05-04 0 Thu CL1 na 1 FW1
    1 1871-05-05 0 Fri BS1 na 1 WS3
    2 1871-05-06 0 Sat CL1 na 2 RC1
    3 1871-05-08 0 Mon CL1 na 3 CH1
    4 1871-05-09 0 Tue BS1 na 2 TRO

    通过对列的优化,我们是pandas的内存用量从861.6兆降到104.28兆,有效降低88%。

    分析棒球比赛

    现在我们有了优化后的数据,可以进行一些分析。我们先看看比赛日的分布情况。

    optimized_gl['year'] = optimized_gl.date.dt.year
    games_per_day = optimized_gl.pivot_table(index='year',columns='day_of_week',values='date',aggfunc=len)
    games_per_day = games_per_day.divide(games_per_day.sum(axis=1),axis=0)
    
    ax = games_per_day.plot(kind='area',stacked='true')
    ax.legend(loc='upper right')
    ax.set_ylim(0,1)
    plt.show()

    我们可以看到,1920年代之前,周日棒球赛很少是在周日的,随后半个世纪才逐渐增多。

    我们也看到最后50年的比赛日分布变化相对比较平稳。

    我们来看看比赛时长的逐年变化。

    game_lengths = optimized_gl.pivot_table(index='year', values='length_minutes')
    game_lengths.reset_index().plot.scatter('year','length_minutes')
    plt.show()

    看来棒球比赛时长从1940年代之后逐渐变长。

    总结

    我们学习了pandas如何存储不同的数据类型,并利用学到的知识将我们的pandas dataframe的内存用量降低了近90%,仅仅只用了一点简单的技巧:

    • 将数值型列降级到更高效的类型
    • 将字符串列转换为类别类型
    展开全文
  • 上一篇文章 写的是处理GB级数据时datatable比pandas会更高效,但是datatable使用起来毕竟不如pandas来的顺手。所以今天准备介绍pandas的三个...
  • python pandas处理大数据节省内存的方法 数值类型的列进行降级处理 字符串类型的列转化为类别类型(category) 字符串类型的列的类别数超过总行数的一半时,建议使用object类型 ''' 减少内存的使用 ''' def reduce...
  • Pandas并不具备多处理器,并且处理较大的数据集速度很慢。笔者消耗在等待Pandas读取一堆文件或对其进行汇总计算上的时间太多太多了。最近,笔者发现了一个更好的工具可以更新数据处理管道,使这些CPU内核正常工作! ...
  • 大文本数据的读写 有时候我们会拿到一些很大的文本文件,完整读入内存,读入的过程会很慢,甚至可能无法读入内存,或者可以读入内存,但是没法进行进一步的计算,这个时候如果我们不是要进行很复杂...import pandas as
  • https://www.dataquest.io/blog/pandas-big-data/ 原文链接 https://zhuanlan.zhihu.com/p/28531346 中文整理版
  • 近期的工作和Hive SQL打交道比较多,偶尔遇到一些SQL不好解决的问题,会将文件下载下来用pandas处理,由于数据量比较大,因此有一些相关的经验可以和大家分享 近期的工作和Hive SQL打交道比较多,偶尔遇到一些SQL...
  • refer : https://yq.aliyun.com/articles/530060?spm=a2c4e.11153940.blogcont181452.16.413f2ef21NKngz# http://www.datayuan.cn/article/6737.htm ...
  • 这篇文章简单介绍了在Python中利用Pandas处理大数据的过程,Pandas库的使用能够很好地展现数据结构,是近来Python项目中经常被使用使用的热门技术,需要的朋友可以参考下 数据分析领域,最热门的莫过于Python和R语言,...
  • 目录 将内存使用量减少高达90%的方法 使用棒球比赛日志 数据帧的内部表示 了解子类型 ...当使用具有小数据(小于100兆字节)的pandas时,性能很少成为问题。当我们迁移到更大的数据(100兆字节到...
  • pandas panel data analysis panel 面板数据 计量经济学 用来存储三维数据 为什么使用pandas 便捷处理数据的能力 读取文件方便,支持多种数据文件类型 封装了Matplotlib,Numpy的画图计算 核心数据结构 DataFrame ...
  • 近期的工作和Hive SQL打交道比较多,偶尔遇到一些SQL不好解决的问题,会将文件下载下来用pandas处理,由于数据量比较大,因此有一些相关的经验可以和大家分享。 大文本数据的读写 有时候我们会拿到一些很大的...
  • python不用Pandas包和用pandas处理数据集
  • DataFrame是一个重量级的数据结构,当一个dataframe比较大,占据较大内存的时候,同时又需要对这个dataframe做较复杂或者复杂度非O(1)的操作时,会由于内存占用过大而导致处理速度极速下降。 对此,我们的方法是...
  • Pandas使用一个二维的数据结构DataFrame来表示表格式的数据,相比较于Numpy,Pandas可以存储混合的数据结构,同时使用NaN来表示缺失的数据,而不用像Numpy一样要手工处理缺失的数据,并且Pandas使用轴标签来表示行和...
  • pandas分析csv数据

    2020-03-11 08:30:37
    pandas使用总结1 pandas 处理大数据的技巧1.1 分块读取 1 pandas 处理大数据的技巧 1.1 分块读取 import pandas as pd data_path = r'C:\Users\bucho\database\csvdata' file_name = r'2019.csv' csv_path = os....
1 2 3 4 5 ... 20
收藏数 7,781
精华内容 3,112