• 博文1:pandas.read_csv——分块读取大文件 ... 今天在读取一个超大csv文件的时候,遇到困难...首先使用office打不开然后在python中使用基本的pandas.read_csv打开文件时:MemoryError最后查阅read_csv文档发现可以

    博文1:pandas.read_csv——分块读取大文件

    http://blog.csdn.net/zm714981790/article/details/51375475

    今天在读取一个超大csv文件的时候,遇到困难:

    • 首先使用office打不开
    • 然后在python中使用基本的pandas.read_csv打开文件时:MemoryError
    • 最后查阅read_csv文档发现可以分块读取。
    • read_csv中有个参数chunksize,通过指定一个chunksize分块大小来读取文件,返回的是一个可迭代的对象TextFileReader,IO Tools 举例如下:
    In [138]: reader = pd.read_table('tmp.sv', sep='|', chunksize=4)
    
    In [139]: reader
    Out[139]: <pandas.io.parsers.TextFileReader at 0x120d2f290>
    
    In [140]: for chunk in reader:
       .....:     print(chunk)
       .....: 
       Unnamed: 0         0         1         2         3
    0           0  0.469112 -0.282863 -1.509059 -1.135632
    1           1  1.212112 -0.173215  0.119209 -1.044236
    2           2 -0.861849 -2.104569 -0.494929  1.071804
    3           3  0.721555 -0.706771 -1.039575  0.271860
       Unnamed: 0         0         1         2         3
    0           4 -0.424972  0.567020  0.276232 -1.087401
    1           5 -0.673690  0.113648 -1.478427  0.524988
    2           6  0.404705  0.577046 -1.715002 -1.039268
    3           7 -0.370647 -1.157892 -1.344312  0.844885
       Unnamed: 0         0        1         2         3
    0           8  1.075770 -0.10905  1.643563 -1.469388
    1           9  0.357021 -0.67460 -1.776904 -0.968914
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 指定iterator=True 也可以返回一个可迭代对象TextFileReader :
    In [141]: reader = pd.read_table('tmp.sv', sep='|', iterator=True)
    
    In [142]: reader.get_chunk(5)
    Out[142]: 
       Unnamed: 0         0         1         2         3
    0           0  0.469112 -0.282863 -1.509059 -1.135632
    1           1  1.212112 -0.173215  0.119209 -1.044236
    2           2 -0.861849 -2.104569 -0.494929  1.071804
    3           3  0.721555 -0.706771 -1.039575  0.271860
    4           4 -0.424972  0.567020  0.276232 -1.087401
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    • 我需要打开的数据集是个csv文件,大小为3.7G,并且对于数据一无所知,所以首先打开前5行观察数据的类型,列标签等等
    chunks = pd.read_csv('train.csv',iterator = True)
    chunk = chunks.get_chunk(5)
    print chunk
    '''
                 date_time  site_name  posa_continent  user_location_country  
    0  2014-08-11 07:46:59          2               3                     66   
    1  2014-08-11 08:22:12          2               3                     66   
    2  2014-08-11 08:24:33          2               3                     66   
    3  2014-08-09 18:05:16          2               3                     66   
    4  2014-08-09 18:08:18          2               3                     66   
    '''
    博文2:python大规模数据处理技巧之一:数据常用操作

    http://blog.csdn.net/asdfg4381/article/details/51689344

    面对读取上G的数据,Python不能像做简单代码验证那样随意,必须考虑到相应的代码的实现形式将对效率的影响。如下所示,对pandas对象的行计数实现方式不同,运行的效率差别非常大。虽然时间看起来都微不足道,但一旦运行次数达到百万级别时,其运行时间就根本不可能忽略不计了:

    p1

    故接下来的几个文章将会整理下渣渣在关于在大规模数据实践上遇到的一些问题,文章中总结的技巧基本是基于pandas,有错误之处望指正。

    1、外部csv文件读写


    大数据量csv读入到内存


    • 分析思路:数据量非常大时,比如一份银行一个月的流水账单,可能有高达几千万的record。对于一般性能的计算机,有或者是读入到特殊的数据结构中,内存的存储可能就非常吃力了。考虑到我们使用数据的实际情况,并不需要将所有的数据提取出内存。当然读入数据库是件比较明智的做法。若不用数据库呢?可将大文件拆分成小块按块读入后,这样可减少内存的存储与计算资源
    • 注意事项:open(file.csv)与pandas包的pd.read_csv(file.csv ): python32位的话会限制内存,提示太大的数据导致内存错误。解决方法是装python64位。如果嫌python各种包安装过程麻烦,可以直接安装Anaconda2 64位版本
    • 简易使用方法:
        chunker = pd.read_csv(PATH_LOAD, chunksize = CHUNK_SIZE)
    • 1
    • 1
    • 读取需要的列:
        columns = ("date_time",  "user_id")
        chunks_train = pd.read_csv(filename, usecols = columns, chunksize = 100000)
    • 1
    • 2
    • 1
    • 2

    chunker对象指向了多个分块对象,但并没有将实际数据先读入,而是在提取数据时才将数据提取进来。数据的处理和清洗经常使用分块的方式处理,这能大大降低内存的使用量,但相比会更耗时一些

    • 分块读取chunk中的每一行:
        for rawPiece in chunker_rawData:
            current_chunk_size = len(rawPiece.index)   #rawPiece 是dataframe
            for i in range(current_chunk_size ):
                timeFlag = timeShape(rawPiece.ix[i])   #获取第i行的数据
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    将数据存到硬盘


    • 直接写出到磁盘:
        data.to_csv(path_save, index = False, mode = 'w')`
    • 1
    • 1
    • 分块写出到磁盘:
    1. 对于第一个分块使用pandas包的存储IO: 
      • 保留header信息,‘w’模式写入
      • data.to_csv(path_save, index = False, mode = 'w')
    2. 接下的分块写入 
      • 去除header信息,‘a’模式写入,即不删除原文档,接着原文档后继续写
      • data.to_csv(path_save, index = False, header = False, mode = a')
    • 少量的数据写出:

    少量的数据用pickle(cPickle更快)输出和读取,非常方便 ,下面分别是写出和读入

    写出:

        import cPickle as pickle
        def save_trainingSet(fileLoc, X, y):
            pack = [X, y]
            with open(fileLoc, 'w') as f:
                pickle.dump(pack, f)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    读入:

        import cPickle as pickle
        def read_trainingSet(fileLoc):
            with open(fileLoc, 'r') as f:
                pack = pickle.load(f)
            return pack[0], pack[1]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    高效读取外部csv到python内部的list数据结构


    • 效率低下的方法:使用pd读入需要从pd转换到python本身的数据结构,多此一举
        userList = []
        content = pd.read_csv(filename)
        for i in range(len(content)):
            line = content.ix[i]['id']
            userList.append(line)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5
    • 效率高的方法:直接将外部数据读入进来
        userList = []
        f = open(filename)
        content = f.readlines()
        for line in content:
            line = line.replace('\n', '').split(',')
            userList.append(line)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、数据分析时常用数据结构之间的转化


    数据集的横向与纵向合并


    • 简单地横向合并数据集:
    • 问题分析: 
      • 纵向的合并使用list并不好,因为需要去拆解list的每一个行元素,并用extend去拓展每一行的纵向元素
      • 最好使用dataframe中的concat函数:c = pd.concat([a, b], axis = 1),当axis=0时表示合并行(以行为轴)
        inx1 = DataFrame(np.random.randn(nSample_neg), columns = ['randVal'])
        inx2 = DataFrame(range(nSample_neg), columns = ['inxVal'])
        inx = pd.concat([inx1, inx2], axis = 1)
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3
    • 类似数据库的表合并:join(待完整)
        ret = ret.join(dest_small, on="srch_destination_id", how='left', rsuffix="dest")
    • 1
    • 1
    • 简单纵向合并数据集:
    • 纵向合并数据集可以考虑一下几种方法: 
      • 读取数据为list格式,使用append函数逐行读取
      • 将数据集转换为pandas中的dataframe格式,使用dataframe的merge与concat方法
    • 方法: 
      • 方法一:使用dataframe读入,使用concat把每行并起来
      • 方法二:先使用list读入并起来,最后转换成dataframe
      • 方法三:先使用list读入并起来大块的list,每块list转换成dataframe后用concat合并起来
    • 比较:方法一由于concat的静态性,每次要重新分配资源,故跑起来很慢; 方法二与三:会快很多,但具体没有测试,以下是使用方法三的代码:
        data = []
        cleanedPiece = []
        for i in range(CHUNK_SIZE):
            line = rawPiece.ix[i]
            uid = [line['user_id'], line['item_id'],
                line['behavior_type'], timeFlag]
            cleanedPiece.append(uid)
        cleanedPiece = DataFrame(cleanedPiece, columns = columns)
        data = pd.concat([data, cleanedPiece], axis = 0)



    展开全文
  • 如果你有个5、6 G 大小的文件,想把文件内容读出来做一些处理然后存到另外的文件去,你会使用什么进行处理呢?不用在线等,给几个错误示范:有人用...Python处理大数据的劣势: 1、python线程有gil,通俗说就是多...

    如果你有个5、6 G 大小的文件,想把文件内容读出来做一些处理然后存到另外的文件去,你会使用什么进行处理呢?不用在线等,给几个错误示范:有人用multiprocessing 处理,但是效率非常低。于是,有人用python
    处理大文件还是会存在效率上的问题。因为效率只是和预期的时间有关,不会报错,报错代表程序本身出现问题了~

    Python处理大数据的劣势:

    1、python线程有gil,通俗说就是多线程的时候只能在一个核上跑,浪费了多核服务器

    2、python执行效率不高,在处理大数据的时候,效率不高

    3、绝大部分的大公司,用java处理大数据不管是环境也好,积累也好,都会好很多

    Python处理数据的优势(不是处理大数据):

    1、异常快捷的开发速度,代码量巨少

    2、丰富的数据处理包,不管正则也好,html解析啦,xml解析啦,用起来非常方便

    3、内部类型使用成本巨低,不需要额外怎么操作(java,c++用个map都很费劲)

    4、公司中,很大量的数据处理工作工作是不需要面对非常大的数据的

    5、巨大的数据不是语言所能解决的,需要处理数据的框架(hadoop, mpi。。。。)虽然小众,但是python还是有处理大数据的框架的,或者一些框架也支持python

    6、编码问题处理起来太太太方便了

    结论:

    1、python可以处理大数据

    2、python处理大数据不一定是最优的选择

    1. python和其他语言(公司主推的方式)并行使用是非常不错的选择

    2. 因为开发速度,你如果经常处理数据,而且喜欢linux终端,而且经常处理不大的数据(100m一下),最好还是熟悉一下python

    为什么用python处理大文件总有效率问题?

    如果工作需要,立刻处理一个大文件,你需要注意两点:

    一、大型文件的读取效率

    面对100w行的大型数据,经过测试各种文件读取方式,得出结论:

    with open(filename,“rb”) as f:

    for fLine in f:

    pass方式最快,100w行全遍历2.7秒。基本满足中大型文件处理效率需求。如果rb改为r,慢6倍。但是此方式处理文件,fLine为bytes类型。但是python自行断行,仍旧能很好的以行为单位处理读取内容。

    二、文本处理效率问题

    这里举例ascii定长文件,因为这个也并不是分隔符文件,所以打算采用列表操作实现数据分割。但是问题是处理20w条数据,时间急剧上升到12s。本以为是byte.decode增加了时间。遂去除decode全程bytes处理。但是发现效率还是很差。

    最后用最简单方式测试,首次运行,最简单方式也要7.5秒100w次。

    那么关于python处理大文件的技巧,从网络整理三点:列表、文件属性、字典三个点来看看。

    1.列表处理

    def fun(x):尽量选择集合、字典数据类型,千万不要选择列表,列表的查询速度会超级慢,同样的,在已经使用集合或字典的情况下,不要再转化成列表进行操作,比如:

    values_count = 0

    不要用这种的

    if values in dict.values():

    values_count += 1

    尽量用这种的

    if keys,values in dict:

    values_count += 1

    后者的速度会比前者快好多好多。

    2、对于文件属性

    如果遇到某个文件,其中有属性相同的,但又不能进行去重操作,没有办法使用集合或字典时,可以增加属性,比如将原数据重新映射出一列计数属性,让每一条属性具有唯一性,从而可以用字典或集合处理:

    return ‘(’ + str(x) + ‘, 1)’

    list(map(fun,[1,2,3]))

    使用map函数将多个相同属性增加不同项。

    3、对于字典

    多使用iteritems()少使用items(),iteritems()返回迭代器:

    d = {‘a’:1,‘b’:2}

    for i in d.items() :

    … print i

    (‘a’,1)

    (‘b’,2)

    for k,v in d.iteritems() :

    … print k,v

    (‘a’,1)

    (‘b’,2)

    字典的items函数返回的是键值对的元组的列表,而iteritems使用的是键值对的generator,items当使用时会调用整个列表 iteritems当使用时只会调用值。

    除了以下5个python使用模块,你还有什么技巧解决大文件运行效率的问题吗?

    1. 读写文件技术,今后会用到测试数据的参数化和测试报告写作功能中~

    2. 数据处理技术,今后测试脚本的测试数据处理过程可以用到~

    3. 数据统计分析技术,今后会在测试结果分析中用到

    4. 图表展示技术,在今后的测试框架中相关测试报告会用到

    5. 程序自动触发技术,可用于测试脚本程序的自动执行。

    展开全文
  • 如果你有个5、6 G 大小的文件,想把文件内容读出来做一些处理然后存到另外的文件去,你会使用什么进行处理呢?不用在线等,给几个错误示范:有人用...Python处理大数据的劣势: 1、python线程有gil,通俗说就是多线...

    如果你有个5、6 G 大小的文件,想把文件内容读出来做一些处理然后存到另外的文件去,你会使用什么进行处理呢?不用在线等,给几个错误示范:有人用multiprocessing 处理,但是效率非常低。于是,有人用python处理大文件还是会存在效率上的问题。因为效率只是和预期的时间有关,不会报错,报错代表程序本身出现问题了~

    Python处理大数据的劣势:

    1、python线程有gil,通俗说就是多线程的时候只能在一个核上跑,浪费了多核服务器

    2、python执行效率不高,在处理大数据的时候,效率不高

    3、绝大部分的大公司,用java处理大数据不管是环境也好,积累也好,都会好很多

    Python处理数据的优势(不是处理大数据):

    1、异常快捷的开发速度,代码量巨少

    2、丰富的数据处理包,不管正则也好,html解析啦,xml解析啦,用起来非常方便

    3、内部类型使用成本巨低,不需要额外怎么操作(java,c++用个map都很费劲)

    4、公司中,很大量的数据处理工作工作是不需要面对非常大的数据的

    5、巨大的数据不是语言所能解决的,需要处理数据的框架(hadoop, mpi。。。。)虽然小众,但是python还是有处理大数据的框架的,或者一些框架也支持python

    6、编码问题处理起来太太太方便了

    结论:

    1、python可以处理大数据

    2、python处理大数据不一定是最优的选择

    3. python和其他语言(公司主推的方式)并行使用是非常不错的选择

    4. 因为开发速度,你如果经常处理数据,而且喜欢linux终端,而且经常处理不大的数据(100m一下),最好还是熟悉一下python

    为什么用python处理大文件总有效率问题?

    如果工作需要,立刻处理一个大文件,你需要注意两点:

    一、大型文件的读取效率

    面对100w行的大型数据,经过测试各种文件读取方式,得出结论:

    with open(filename,‘rb’) as f:

    for fLine in f:

    pass

    方式最快,100w行全遍历2.7秒。基本满足中大型文件处理效率需求。如果rb改为r,慢6倍。但是此方式处理文件,fLine为bytes类型。但是python自行断行,仍旧能很好的以行为单位处理读取内容。

    二、文本处理效率问题

    这里举例ascii定长文件,因为这个也并不是分隔符文件,所以打算采用列表操作实现数据分割。但是问题是处理20w条数据,时间急剧上升到12s。本以为是byte.decode增加了时间。遂去除decode全程bytes处理。但是发现效率还是很差。

    最后用最简单方式测试,首次运行,最简单方式也要7.5秒100w次。

    那么关于python处理大文件的技巧,从网络整理三点:列表、文件属性、字典三个点来看看。

    1.列表处理

    def fun(x):尽量选择集合、字典数据类型,千万不要选择列表,列表的查询速度会超级慢,同样的,在已经使用集合或字典的情况下,不要再转化成列表进行操作,比如:

    values_count = 0
    
    

    不要用这种的

    
    if values in dict.values():
    
    values_count += 1
    
    

    尽量用这种的

    if keys,values in dict:
    
    values_count += 1
    
    

    后者的速度会比前者快好多好多。

    2、对于文件属性

    如果遇到某个文件,其中有属性相同的,但又不能进行去重操作,没有办法使用集合或字典时,可以增加属性,比如将原数据重新映射出一列计数属性,让每一条属性具有唯一性,从而可以用字典或集合处理:

    return '(' + str(x) + ', 1)'
    
    list(map(fun,[1,2,3]))
    
    

    使用map函数将多个相同属性增加不同项。

    3、对于字典

    多使用iteritems()少使用items(),iteritems()返回迭代器:

    >>> d = {'a':1,'b':2}
    
    >>> for i in d.items() :
    
    ('a',1)
    
    ('b',2)
    
    >>> for k,v in d.iteritems() :
    
    ... print k,v
    
    ('a',1)
    
    ('b',2)
    
    

    字典的items函数返回的是键值对的元组的列表,而iteritems使用的是键值对的generator,items当使用时会调用整个列表 iteritems当使用时只会调用值。

    对Python感兴趣或者是正在学习的小伙伴,可以加入我们的Python学习扣qun:784758214,看看前辈们是如何学习的!从基础的python脚本到web开发、爬虫、django、数据挖掘等,零基础到项目实战的资料都有整理。送给每一位python的小伙伴!分享一些学习的方法和需要注意的小细节,点击加入我们的 python学习者聚集地

    除了以下5个python使用模块,你还有什么技巧解决大文件运行效率的问题吗?

    1. 读写文件技术,今后会用到测试数据的参数化和测试报告写作功能中~

    2. 数据处理技术,今后测试脚本的测试数据处理过程可以用到~

    3. 数据统计分析技术,今后会在测试结果分析中用到

    4. 图表展示技术,在今后的测试框架中相关测试报告会用到

    5. 程序自动触发技术,可用于测试脚本程序的自动执行。

    展开全文
  • 本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。 布隆过滤器 (Bloom Filter) 第一步我们先要实现一个布隆过滤器。 布隆过滤器是大数据领域的一个常见算法,它的...

    搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。

    布隆过滤器 (Bloom Filter)

    第一步我们先要实现一个布隆过滤器

    布隆过滤器是大数据领域的一个常见算法,它的目的是过滤掉那些不是目标的元素。也就是说如果一个要搜索的词并不存在与我的数据中,那么它可以以很快的速度返回目标不存在。

    让我们看看以下布隆过滤器的代码:

    class Bloomfilter(object):
        """
        A Bloom filter is a probabilistic data-structure that trades space for accuracy
        when determining if a value is in a set.  It can tell you if a value was possibly
        added, or if it was definitely not added, but it can't tell you for certain that
        it was added.
        """
        def __init__(self, size):
            """Setup the BF with the appropriate size"""
            self.values = [False] * size
            self.size = size
    
        def hash_value(self, value):
            """Hash the value provided and scale it to fit the BF size"""
            return hash(value) % self.size
    
        def add_value(self, value):
            """Add a value to the BF"""
            h = self.hash_value(value)
            self.values[h] = True
    
        def might_contain(self, value):
            """Check if the value might be in the BF"""
            h = self.hash_value(value)
            return self.values[h]
    
        def print_contents(self):
            """Dump the contents of the BF for debugging purposes"""
            print self.values
    
    • 基本的数据结构是个数组(实际上是个位图,用1/0来记录数据是否存在),初始化是没有任何内容,所以全部置False。实际的使用当中,该数组的长度是非常大的,以保证效率。
    • 利用哈希算法来决定数据应该存在哪一位,也就是数组的索引
    • 当一个数据被加入到布隆过滤器的时候,计算它的哈希值然后把相应的位置为True
    • 当检查一个数据是否已经存在或者说被索引过的时候,只要检查对应的哈希值所在的位的True/Fasle

    看到这里,大家应该可以看出,如果布隆过滤器返回False,那么数据一定是没有索引过的,然而如果返回True,那也不能说数据一定就已经被索引过。在搜索过程中使用布隆过滤器可以使得很多没有命中的搜索提前返回来提高效率。

    我们看看这段 code是如何运行的:

    bf = Bloomfilter(10)
    bf.add_value('dog')
    bf.add_value('fish')
    bf.add_value('cat')
    bf.print_contents()
    bf.add_value('bird')
    bf.print_contents()
    # Note: contents are unchanged after adding bird - it collides
    for term in ['dog', 'fish', 'cat', 'bird', 'duck', 'emu']:
        print '{}: {} {}'.format(term, bf.hash_value(term), bf.might_contain(term))
    

    结果:

    [False, False, False, False, True, True, False, False, False, True]
    [False, False, False, False, True, True, False, False, False, True]
    dog: 5 True
    fish: 4 True
    cat: 9 True
    bird: 9 True
    duck: 5 True
    emu: 8 False
    

    首先创建了一个容量为10的的布隆过滤器

     

    然后分别加入 ‘dog’,‘fish’,‘cat’三个对象,这时的布隆过滤器的内容如下:

     

    然后加入‘bird’对象,布隆过滤器的内容并没有改变,因为‘bird’和‘fish’恰好拥有相同的哈希。

     

    最后我们检查一堆对象('dog', 'fish', 'cat', 'bird', 'duck', 'emu')是不是已经被索引了。结果发现‘duck’返回True,2而‘emu’返回False。因为‘duck’的哈希恰好和‘dog’是一样的。

     

    分词

    下面一步我们要实现分词。 分词的目的是要把我们的文本数据分割成可搜索的最小单元,也就是词。这里我们主要针对英语,因为中文的分词涉及到自然语言处理,比较复杂,而英文基本只要用标点符号就好了。这里向大家推荐一个大数据交流圈q裙:894951460。

    下面我们看看分词的代码:

    def major_segments(s):
        """
        Perform major segmenting on a string.  Split the string by all of the major
        breaks, and return the set of everything found.  The breaks in this implementation
        are single characters, but in Splunk proper they can be multiple characters.
        A set is used because ordering doesn't matter, and duplicates are bad.
        """
        major_breaks = ' '
        last = -1
        results = set()
    
        # enumerate() will give us (0, s[0]), (1, s[1]), ...
        for idx, ch in enumerate(s):
            if ch in major_breaks:
                segment = s[last+1:idx]
                results.add(segment)
    
                last = idx
    
        # The last character may not be a break so always capture
        # the last segment (which may end up being "", but yolo)    
        segment = s[last+1:]
        results.add(segment)
    
        return results
    

    主要分割

    主要分割使用空格来分词,实际的分词逻辑中,还会有其它的分隔符。例如Splunk的缺省分割符包括以下这些,用户也可以定义自己的分割符。

    ] < > ( ) { } | ! ; , ' " * \n \r \s \t & ? + %21 %26 %2526 %3B %7C %20 %2B %3D -- %2520 %5D %5B %3A %0A %2C %28 %29

    def minor_segments(s):
        """
        Perform minor segmenting on a string.  This is like major
        segmenting, except it also captures from the start of the
        input to each break.
        """
        minor_breaks = '_.'
        last = -1
        results = set()
    
        for idx, ch in enumerate(s):
            if ch in minor_breaks:
                segment = s[last+1:idx]
                results.add(segment)
    
                segment = s[:idx]
                results.add(segment)
    
                last = idx
    
        segment = s[last+1:]
        results.add(segment)
        results.add(s)
    
        return results
    

    次要分割

    次要分割和主要分割的逻辑类似,只是还会把从开始部分到当前分割的结果加入。例如“1.2.3.4”的次要分割会有1,2,3,4,1.2,1.2.3

    def segments(event):
        """Simple wrapper around major_segments / minor_segments"""
        results = set()
        for major in major_segments(event):
            for minor in minor_segments(major):
                results.add(minor)
        return results
    

    分词的逻辑就是对文本先进行主要分割,对每一个主要分割在进行次要分割。然后把所有分出来的词返回。

    我们看看这段 code是如何运行的:

    for term in segments('src_ip = 1.2.3.4'):
            print term
    
    src
    1.2
    1.2.3.4
    src_ip
    3
    1
    1.2.3
    ip
    2
    =
    4
    

    搜索

    好了,有个分词和布隆过滤器这两个利器的支撑后,我们就可以来实现搜索的功能了。

    上代码:

    class Splunk(object):
        def __init__(self):
            self.bf = Bloomfilter(64)
            self.terms = {}  # Dictionary of term to set of events
            self.events = []
    
        def add_event(self, event):
            """Adds an event to this object"""
    
            # Generate a unique ID for the event, and save it
            event_id = len(self.events)
            self.events.append(event)
    
            # Add each term to the bloomfilter, and track the event by each term
            for term in segments(event):
                self.bf.add_value(term)
    
                if term not in self.terms:
                    self.terms[term] = set()
                self.terms[term].add(event_id)
    
        def search(self, term):
            """Search for a single term, and yield all the events that contain it"""
    
            # In Splunk this runs in O(1), and is likely to be in filesystem cache (memory)
            if not self.bf.might_contain(term):
                return
    
            # In Splunk this probably runs in O(log N) where N is the number of terms in the tsidx
            if term not in self.terms:
                return
    
            for event_id in sorted(self.terms[term]):
                yield self.events[event_id]
    
    • Splunk代表一个拥有搜索功能的索引集合
    • 每一个集合中包含一个布隆过滤器,一个倒排词表(字典),和一个存储所有事件的数组
    • 当一个事件被加入到索引的时候,会做以下的逻辑
      • 为每一个事件生成一个unqie id,这里就是序号
      • 对事件进行分词,把每一个词加入到倒排词表,也就是每一个词对应的事件的id的映射结构,注意,一个词可能对应多个事件,所以倒排表的的值是一个Set。倒排表是绝大部分搜索引擎的核心功能。
    • 当一个词被搜索的时候,会做以下的逻辑
      • 检查布隆过滤器,如果为假,直接返回
      • 检查词表,如果被搜索单词不在词表中,直接返回
      • 在倒排表中找到所有对应的事件id,然后返回事件的内容

    我们运行下看看把:

    s = Splunk()
    s.add_event('src_ip = 1.2.3.4')
    s.add_event('src_ip = 5.6.7.8')
    s.add_event('dst_ip = 1.2.3.4')
    
    for event in s.search('1.2.3.4'):
        print event
    print '-'
    for event in s.search('src_ip'):
        print event
    print '-'
    for event in s.search('ip'):
        print event
    
    src_ip = 1.2.3.4
    dst_ip = 1.2.3.4
    -
    src_ip = 1.2.3.4
    src_ip = 5.6.7.8
    -
    src_ip = 1.2.3.4
    src_ip = 5.6.7.8
    dst_ip = 1.2.3.4
    

    是不是很赞!

    更复杂的搜索

    更进一步,在搜索过程中,我们想用And和Or来实现更复杂的搜索逻辑。

    上代码:

    class SplunkM(object):
        def __init__(self):
            self.bf = Bloomfilter(64)
            self.terms = {}  # Dictionary of term to set of events
            self.events = []
    
        def add_event(self, event):
            """Adds an event to this object"""
    
            # Generate a unique ID for the event, and save it
            event_id = len(self.events)
            self.events.append(event)
    
            # Add each term to the bloomfilter, and track the event by each term
            for term in segments(event):
                self.bf.add_value(term)
                if term not in self.terms:
                    self.terms[term] = set()
    
                self.terms[term].add(event_id)
    
        def search_all(self, terms):
            """Search for an AND of all terms"""
    
            # Start with the universe of all events...
            results = set(range(len(self.events)))
    
            for term in terms:
                # If a term isn't present at all then we can stop looking
                if not self.bf.might_contain(term):
                    return
                if term not in self.terms:
                    return
    
                # Drop events that don't match from our results
                results = results.intersection(self.terms[term])
    
            for event_id in sorted(results):
                yield self.events[event_id]
    
        def search_any(self, terms):
            """Search for an OR of all terms"""
            results = set()
    
            for term in terms:
                # If a term isn't present, we skip it, but don't stop
                if not self.bf.might_contain(term):
                    continue
                if term not in self.terms:
                    continue
    
                # Add these events to our results
                results = results.union(self.terms[term])
    
            for event_id in sorted(results):
                yield self.events[event_id]
    

    利用Python集合的intersection和union操作,可以很方便的支持And(求交集)和Or(求合集)的操作。

    运行结果如下:

    s = SplunkM()
    s.add_event('src_ip = 1.2.3.4')
    s.add_event('src_ip = 5.6.7.8')
    s.add_event('dst_ip = 1.2.3.4')
    
    for event in s.search_all(['src_ip', '5.6']):
        print event
    print '-'
    for event in s.search_any(['src_ip', 'dst_ip']):
        print event
    
    src_ip = 5.6.7.8
    -
    src_ip = 1.2.3.4
    src_ip = 5.6.7.8
    dst_ip = 1.2.3.4
    

    总结

    以上的代码只是为了说明大数据搜索的基本原理,包括布隆过滤器,分词和倒排表。如果大家真的想要利用这代码来实现真正的搜索功能,还差的太远。

    结语

    感谢您的观看,如有不足之处,欢迎批评指正。

    获取资料

    本次给大家推荐一个免费的学习群,里面概括数据仓库/源码解析/Python/Hadoop/Flink/Spark/Storm/Hive以及面试资源等。
    对大数据开发技术感兴趣的同学,欢迎加入Q群:894951460,不管你是小白还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。
    最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。

    展开全文
  • 二、使用python脚本程序将目标excel文件中的列头写入,本文省略该部分的code展示,可自行网上查询 三、以下code内容为:实现从接口获取到的数据值写入excel的整体步骤 1、整体思路: (1)、根据每日调取接口的...

    欢迎关注【无量测试之道】公众号,回复【领取资源】,
    Python编程学习资源干货、
    Python+Appium框架APP的UI自动化、
    Python+Selenium框架Web的UI自动化、
    Python+Unittest框架API自动化、

    资源和代码 免费送啦~
    文章下方有公众号二维码,可直接微信扫一扫关注即可。

    一、在工程目录中新建一个excel文件

    二、使用python脚本程序将目标excel文件中的列头写入,本文省略该部分的code展示,可自行网上查询

    三、以下code内容为:实现从接口获取到的数据值写入excel的整体步骤

           1、整体思路:

                 (1)、根据每日调取接口的日期来作为excel文件中:列名为“收集日期”的值

                 (2)、程序默认是每天会定时调取接口并获取接口的返回值并写入excel中(我使用的定时任务是:linux下的contab)

                 (3)、针对接口异常未正确返回数据时,使用特殊符号如:NA代替并写入excel文件中(后期使用excel数据做分析时有用)

     

            2、完整代码如下:

    import requests, xlrd, os, sys, urllib3
    from datetime import date, timedelta
    from xlutils.copy import copy
    basedir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    sys.path.append(basedir)
    from lib.mysqldb import mysqldb
    from lib.public_methods import test_login
    
    
    def collect_data():
        """test_rooms.test_kpi卡片下:adr指标值收集"""
        get_all_code_sql = 'select DISTINCT test_code from test_info WHERE open_flag = 1'
        test_code_all = mysqldb("test_data").selectsql(get_all_code_sql)
        test_code_list = []
        adr_insert_data_list = []
        yesterday = (date.today() + timedelta(days=-1)).strftime("%Y-%m-%d")
        adr_insert_data_list.append(yesterday)
        for j in range(len(test_code_all)):
            test_code_list.append(test_code_all[j]["test_code"])
        for m in range(len(test_code_list)):
            url = "https://www.baidu.com/test/api/data/query.json"
            header = {
                "Content-Type": "application/json;charset=UTF-8",
                "Cookie": str(test_login())
            }
            param = {
                "code": "test_rooms.test_kpi",
                "page": 1,
                "pageSize": 1000,
                "params": {
                    "start_date_year": "2019",
                    "start_date_month": "9",
                    "start_date_day": "16",
                    "end_date_year": "2019",
                    "currency_type": "usd",
                    "end_date_day": "16",
                    "end_date_month": "9",
                    "tests": "test_001"
                }
            }
            """替换请求参数中的开始日期"""
            param["params"]["start_date_year"] = str(yesterday).split("-")[0]
            param["params"]["start_date_month"] = str(yesterday).split("-")[1]
            param["params"]["start_date_day"] = str(yesterday).split("-")[2]
            """替换请求参数中的结束日期"""
            param["params"]["end_date_year"] = param["params"]["start_date_year"]
            param["params"]["end_date_month"] = param["params"]["start_date_month"]
            param["params"]["end_date_day"] = param["params"]["start_date_day"]
            param["params"]["tests"] = test_code_list[m]
            urllib3.disable_warnings()
            result = requests.post(url=url, headers=header, json=param, verify=False).json()
            if str(result["data"]["data"]) != "None":
                """adr指标值收集"""
                indicatorList = result["data"]["data"]["test_indicator_list"]
                test_actualorLast_Forecast = result["data"]["data"]["test_actual"]
                new_indicator_actualvalue = {}
                i = 0
                while i < len(indicatorList):
                    dit = {indicatorList[i]: test_actualorLast_Forecast[i]}
                    new_indicator_actualvalue.update(dit)
                    i += 1
                if str(new_indicator_actualvalue["adr"]) == "--":
                    adr_value_result = "NA"
                    adr_insert_data_list.append(adr_value_result)
                else:
                    adr_value_result = new_indicator_actualvalue["adr"]
                    adr_insert_data_list.append(adr_value_result)
            else:
                adr_value_result = "NA"
                adr_insert_data_list.append(adr_value_result)
    
        """adr指标值数据收集入excel路径"""
        workbook = xlrd.open_workbook(basedir + "/data/collect_data_center.xls")  # 打开工作簿
        sheets = workbook.sheet_names()  # 获取工作簿中的所有表格
        worksheet = workbook.sheet_by_name(sheets[0])  # 获取工作簿中所有表格中的的第一个表格
        rows_old = worksheet.nrows  # 获取表格中已存在的数据的行数
        new_workbook = copy(workbook)  # 将xlrd对象拷贝转化为xlwt对象
        new_worksheet = new_workbook.get_sheet(0)  # 获取转化后工作簿中的第一个表格
        for i in range(0, 1):
            for j in range(0, len([adr_insert_data_list][i])):
                new_worksheet.write(i + rows_old, j, [adr_insert_data_list][i][j])  # 追加写入数据,注意是从i+rows_old行开始写入
        new_workbook.save(basedir + "/data/collect_data_center.xls")  # 保存工作簿
        print("adr指标值---xls格式表格【追加】写入数据成功!")

                  3、从步骤2中的代码可看出代码整体分为3个部分:

                        (1)、组装接口参数;

                        (2)、调用接口将接口返回的结果集收集在list中;

                        (3)、将收集的结果写入excel中并保存;

     

                   4、最终excel写入数据的样式如下截图所示:

     

    tips:windows与linux下excel的路径格式需要区分下,以上代码中的"/data/collect_data_center.xls"为linux环境下路径

     

    备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:

    添加关注,一起共同成长吧。

    展开全文
  • Java,Python大数据,哪个发展前景最好?网络上众说纷纷,各自都有优点和缺点,而 Java和Python是编程语言,而大数据则是一系列技术的整合,所以应该分开来看,三者并不能直接进行对比。 三者实际的关系是目标和...
  • 当然,像Spark这类的工具能够胜任处理100G至几个T的大数据集,但要想充分发挥这些工具的优势,通常需要比较贵的硬件设备。而且,这些工具不像pandas那样具有丰富的进行高质量数据清洗、探索和分析的特性。对于中等...
  • python 大数据入门教程

    2018-12-07 17:35:38
    Python大数据行业非常火爆近两年,as a pythonic,所以也得涉足下大数据分析,下面就聊聊它们。 Python数据分析与挖掘技术概述 所谓数据分析,即对已知的数据进行分析,然后提取出一些有价值的信息,比如统计...
  • Python大数据处理方案

    2018-03-26 21:30:37
    Mysql SQLyog导入导出csv文件SQLyog 导出表中数据存为csv文件1. 选择数据库表 --&gt; 右击属性 --&gt; 备份/导出 --&gt; 导出表数据作为 --&gt; 选择cvs --&... 选择下面的“更改” --&...
  • 在数据科学计算、机器学习、以及深度学习领域,Python 是最受欢迎的语言。Python 在数据科学领域,有非常丰富的可以选择,numpy、scipy、pandas、scikit-le...
  • Pandas是python的众多工具中最著名一个,如果你使用python进行数据分析与建模,你一定会用到pandas,pandas已经越来越被广泛的应用于数据探索性分析(EDA),它可以完全媲美甚至超越Excel,目前越来越多的Excel数据...
  • Java和Python是编程语言,而大数据则是一系列技术的整合,所以应该分开来看,三者并不能直接进行对比。 三者实际的关系是目标和实现的包含关系。所以这个问题应该分别为 Java和Python哪个发展前景好?大数据的...
  • 文章大纲python 与hdfs 交互 回写python2 与hdfs在python中直接调用hadoop shell 命令去操作文件python 与 py4j 交互pyspark 直接写文件到磁盘(这个可以搭建一个本地的spark 单机版试试)python docker 搭建spark ...
  • 01-Python大数据+人工智能-学前阶段 02-Python大数据+人工智能-基础阶段 03-Python大数据+人工智能-面向对象 04-Python大数据+人工智能-异常处理 05-Python大数据+人工智能-和模块
  • Python可以直接处理上G的数据;R不行,R分析数据时需要先通过数据库把大数据转化为小数据才能交给R做分析,因此R不可能直接分析行为详单,只能分析统计结果。所以有人说:Python=R+SQL/Hive,并不是没有道理的。 ...
  • 大数据与人工智能时代,掌握Python基础后,我们可以选择数据分析方向、人工智能方向、全栈开发方向...如果想要追赶 Python 的热潮,应该如何学习呢?除了自学之外,多数人都会选择在线课程作为辅助。选择课程的衡量...
  • 简介在本次笔记中主要汇总Python关于大数据处理的一些基础性工具,个人掌握这些工具是从事大数据处理大数据测必备技能主要工具有以下(包括但不限于):numpypandasSciPyScikit-LearnSparkMatplotlib对于上述工具...
  • 课程目录 01-Python大数据+人工智能-学前阶段.zip 02-Python大数据+人工智能-基础阶段.zip ...04-Python大数据+人工智能-异常处理.zip 05-Python大数据+人工智能-和模块.zip 下载地址:百度云盘 ...
  • 自从2004年以后,python的使用率呈线性增长。2011年1月,它被TIOBE编程语言排行榜评为2010年度语言。由于Python语言的简洁性、易读性以及可扩展性,在国外用Python做科学计算的研究机构日益增多,一些知名大学已经...
1 2 3 4 5 ... 20
收藏数 37,910
精华内容 15,164