社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

如何使用Python计算大文件中每个数字的每次出现次数

Peter • 5 年前 • 2119 次点击  

我是Python的初学者,我想知道是否有人能帮我解决这个问题。

我有一个超过600万行的大文本文件,但每行只有一对“x,y”,x和y相对较小。

我要做的是,在Python中,计算我的文件中每出现一对“x,y”,并将它们写在一个excel文档中,每行表示de“y”,每列表示“x”。

我有一个有效的程序,但文件太大,它实际上需要一年多才能完成。

所以我想知道是否有一种更快的方法。

请记住,我在编程方面真的不是很好,因为我刚开始。

非常感谢潜在的答案。

这是我目前的代码:

import xlsxwriter

book = xlsxwriter.Workbook("MyCount.xlsx")

sheet1 = book.add_worksheet('Sheet 1')

sheet1.write(0,0,'y\x')

for i in range (0,1441):
    sheet1.write(0,i+1,i)

for i in range (1,118):
    sheet1.write(i,0,i)

file1=open("Data.txt","r")

count=0

for x in range (0, 1441):
    for y in range (1, 118):
        count=0
        number=f'{x}'+','+f'{y}'+'\n'
        for line in file1.readlines():
            if line == number:
                count+=1
        sheet1.write(y, x+1, count)
        file1.seek(0)

file1.close()
book.close()
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/51410
 
2119 次点击  
文章 [ 3 ]  |  最新文章 5 年前
satyam soni
Reply   •   1 楼
satyam soni    6 年前

我想这对你来说是更优雅的解决方案。将文件读入pandas数据框,按分组并计算对数。

import pandas as pd
d = [(1,2,3),(1,2,4),(1,2,1),(1,1,5),(1,4,5),(1,1,8)]

cntdt = pd.DataFrame(d,columns=['x','y','cnt'])
cntdt.head()

s = cntdt.groupby(['y','x']).size()

#to get the dataframe
s.to_frame('count').reset_index()

#to get the dictionary
s.to_dict()

字典输出:{(1,1):2,(2,1):3,(4,1):1} 数据帧输出:

<table border="1" class="dataframe"> <thead>   <tr style="text-align: right;">     <th></th>     <th>y</th>     <th>x</th>     <th>count</th>   </tr> </thead> <tbody>   <tr>     <th>0</th>     <td>1</td>     <td>1</td>     <td>2</td>   </tr>   <tr>     <th>1</th>     <td>2</td>     <td>1</td>     <td>3</td>   </tr>   <tr>     <th>2</th>     <td>4</td>     <td>1</td>     <td>1</td>   </tr> </tbody></table>
Alexandru Martin
Reply   •   2 楼
Alexandru Martin    6 年前

所以看看这个:

counts = {}

for line in open("data.txt", "r"):
    line = line.split(',')

    number_1 = None
    number_2 = None

    for line_element in line:

        try:
            number = int(line_element)
            if number_1 is None:
                number_1 = number
            else:
                number_2 = number
        except Exception:
            pass

    if number_1 and number_2:
        numbers_couple = '{},{}'.format(number_1, number_2)

        if numbers_couple in counts:
            counts[numbers_couple] += 1
        else:
            counts[numbers_couple] = 1

print(counts)

我的data.txt内容:

a,b,c,20,30,dad,glaas
fdls,cafd,erer,fdesf,2,4534
fdls,cafd,erer,fdesf,2,11

结果是:

{
   '20,30': 1, 
   '2,4534': 1, 
   '2,11': 1
}

您可以使用此结果将其写入您提到的新文件,方法是分割字典的键以获取x和y。

像这样,我已经计算了一个文件中的数对。这就是你要找的吗?请告诉我。

bruno desthuilliers
Reply   •   3 楼
bruno desthuilliers    6 年前

这是Alexandru解决方案的改进版(未经测试…)(注意:Alexandru发布自己的答案时,我已经在写了这个答案,但既然他先发布了,如果它有助于解决您的问题,请给他信用)。

一般的想法是只对文件执行一次单次扫描,而不是连续执行170038(=>1441*118)次顺序扫描,并减少 sheet.write() 调用找到的行数,而不是一遍又一遍地重写同一单元格。

此外,使用函数将有助于更快的执行,因为局部变量访问比全局变量访问更快。

不知道这是否能很快解决你的问题,但至少应该 许多的 比您当前的实现速度快。

注:6米 {(int,int):int} dict很容易放在大多数现代计算机的内存中(只是在我的内存中试过,我的内存已经很忙了),所以这不是问题(而且你已经在内存中读取了整个文件,这可能是更重的wrt/内存…)

from collections import defaultdict

def parse_file():
    counts = defaultdict(int)
    with open("Data.txt") as f:
        for lineno, line in enumerate(f):
            line = line.strip()
            if not line:
                continue
            try:
                xy = tuple(int(i) for i in line.split(","))
            except (TypeError, ValueError) as e:
                print("oops, line {} is broken ? (found '{}')".format(lineno, line))
                continue
            counts[xy] += 1
    return counts


def write_counts(counts):
    book = xlsxwriter.Workbook("MyCount.xlsx")
    sheet1 = book.add_worksheet('Sheet 1')
    sheet1.write(0,0,'y\x')
    for i in range (0,1441):
       sheet1.write(0,i+1,i)
    for i in range (1,118):
        sheet1.write(i,0,i)

    for (x, y), count in counts.items():
        sheet1.write(y, x+1, count)


def main():
    counts = parse_file()
    write_counts(counts)

if __name__ == "__main__":
    main()