![](/img/trans.png)
[英]How to deal with huge amount of categorical data in Machine Learning using Python?
[英]How to deal with large amount of data in Python
我有一个包含大量数据(3 GB)的文本文件。 此文本文件的每一行包含时间,源IP,目标IP和大小。 如您所知,IP地址最后一节中的数字显示端口地址。 我想把这些端口地址带到一个直方图中,我为它做了10 000行数据,但我猜想Python代码不能为大量数据执行。 我简要解释一下我写的代码。 首先,我读取了10 000个数据点,之后我将它们拆分并将所有内容放入名为everything_list的列表中。 只需忽略while循环工作的条件。 后来我将所有端口地址放在一个列表中并绘制了那些的直方图。 现在假设我有数百万条数据线,我首先无法读取它们,更不用说对它们进行分类了。 有人告诉我使用数组,有人告诉我处理数据块,然后再处理另一数据块。 我很困惑所有人说。 有人可以帮我解决这个问题吗?
text_file = open("test.data", "r")
a = text_file.read()
text_file.close()
everything_list = a.split()
source_port_list = []
i=0
while 6+7*i<len(everything_list):
source_element = everything_list[2+7*i]
source_port_position = source_element.rfind('.')
source_port_number = int(source_element[source_port_position + 1:])
source_port_list.append(source_port_number)
i=i+1
import matplotlib.pyplot as plt
import pylab
numBins = 20
plt.hist(source_port_list, numBins, color='red', alpha=0.8)
plt.show()
这是行格式:
15:42:42.719063 IP 129.241.138.133.47843 > 129.63.27.12.2674: tcp 1460
15:42:42.719205 IP 129.241.138.133.47843 > 129.63.27.12.2674: tcp 1460
15:42:42.719209 IP 129.63.57.175.45241 > 62.85.5.142.55455: tcp 0
15:42:42.719213 IP 24.34.41.8.1236 > 129.63.1.23.443: tcp 394
15:42:42.719217 IP 59.167.148.152.25918 > 129.63.57.40.36075: tcp 0
15:42:42.719260 IP 129.63.223.16.2823 > 80.67.87.25.80: tcp 682
15:42:42.719264 IP 129.63.184.118.2300 > 64.111.215.46.80: tcp 0
15:42:42.719269 IP 129.63.184.118.2300 > 64.111.215.46.80: tcp 0
我不知道数据是什么样的,但我认为问题是你试图将它全部保存在内存中。 你需要一点一点地做, 逐一阅读这些行并随时建立直方图。
histogram = {}
with open(...) as f:
for line in f:
ip = ...
if ip in histogram:
histogram[ip] += 1
else:
histogram[ip] = 1
您现在可以绘制直方图,但是请使用plt.plot
而不是plt.hist
因为您已经在histogram
字典中有了频率。
您可以使用正则表达式并在循环外进行编译。
完全以懒惰模式逐行读取文件。
import re
import matplotlib.pyplot as plt
import pylab
r = re.compile(r'(?<=\.)[0-9]{2,5}(?= \>)')
ports = []
for line in open("test.data", "r"):
ports.append(re.search(r, line).group(0))
# determines the number of lines you want to take into account
i = (len(ports) - 6) // 7
# keeps only the first i elements
ports = ports[0:i]
numBins = 20
plt.hist(ports, numBins, color='red', alpha=0.8)
plt.show()
此代码考虑到您只需要(n-6) / 7
第一项, n
是源文件的行数。 如果不太准确,请尝试一些+1/-1
。 最后,消除不需要的项目使您的循环不会因每次迭代中检查条件而麻烦。
编辑:
您可以结合上面的几个方面来获得更简洁有效的代码:
import re
import matplotlib.pyplot as plt
import pylab
r = re.compile(r'(?<=\.)[0-9]{2,5}(?= \>)')
ports = [ re.search(r, line).group(0) for line in open("test.data", "r") ]
ports = ports[0:(len(ports) - 6) // 7]
numBins = 20
plt.hist(ports, numBins, color='red', alpha=0.8)
plt.show()
编辑:
如果您认为您的端口列表太大而无法放入RAM(我觉得不太可能),我的建议是使用端口字典:
ports = {}
for line in open("test.data", "r"):
port = re.search(r, line).group(0)
if not ports.get(port, False):
ports[port] = 0
ports[port] += 1
哪个会给你这样的东西:
>>> ports
{
"8394": 182938,
"8192": 839288,
"1283": 9839
}
请注意,在这种情况下,您必须修改对plt.hist
的调用。
您可以使用split和defaultdict来提高效率:
from collections import defaultdict
d = defaultdict(int)
with open("a_file.txt") as f:
for line in f:
d[line.split()[2].rsplit(".",1)[-1]] += 1
print(d)
defaultdict(<type 'int'>, {'1236': 1, '2300': 1, '47843': 2, '45241': 1, '25918': 1, '2823': 1})
可能还需要检查一下不同的绘制方式,matplotlib并不是最有效的:
听起来你应该逐行迭代并使用正则表达式来查找端口。 尝试这样的事情:
import re
ports = []
with open("path/to/your/text/file.txt", 'r') as infile:
for line in infile:
ports.append(re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.(\d+)", line))
# that regex explained:
# # re.compile(r"""
# # \d{1,3}\. # 1-3 digits followed by a literal .
# # \d{1,3}\. # 1-3 digits followed by a literal .
# # \d{1,3}\. # 1-3 digits followed by a literal .
# # \d{1,3}\. # 1-3 digits followed by a literal .
# # ( # BEGIN CAPTURING GROUP
# # \d+ # 1 or more digits
# # ) # END CAPTURING GROUP""", re.X)
这是假设您的IP /端口已按照注释中的说明进行格式化
IP.IP.IP.IP.PORT
我知道这不是对您的问题的立即答复,但是作为python的新手,有一门很好的Coursera课程涉及该主题。 “为每个人编程(Python)”它是免费的,不会占用你太多的时间。 该课程将于2015年2月2日开始。此外,教科书“信息学的Python:探索信息”也可以免费下载。 在http://www.pythonlearn.com/book.php我希望这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.