{"id":334743,"date":"2022-06-20T15:00:22","date_gmt":"2022-06-20T15:00:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=334743"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=334743","title":{"rendered":"<span>\u0418\u0449\u0435\u043c \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u044b \u0432 \u043c\u0430\u0442\u0447\u0430\u0445 Dota 2 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 Collapse \u043d\u0430 Magnus \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 The International 2021<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0432 Dota 2 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0440\u0435\u0437\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e-\u0440\u043e\u043b\u0438\u043a\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>.mp4<\/code> \u043f\u0440\u0438 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043c\u0430\u0442\u0447\u0435\u0439. \u042f \u043d\u0435 \u0443\u0434\u0435\u0440\u0436\u0430\u043b\u0441\u044f \u0438 \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 aka \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432. \u0412\u043e\u0442 \u0447\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043a\u0430\u0440\u0442\u044b \u0433\u0440\u0430\u043d\u0434-\u0444\u0438\u043d\u0430\u043b\u0430 The International 2021, \u0433\u0434\u0435 Collapse \u0438\u0437 Team Spirit \u043a\u0430\u0442\u0430\u043b PSG.LGD \u043d\u0430 \u0441\u0432\u043e\u0435\u043c Magnus&#8217;\u0435.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/62a703b915db00b462264916\" data-style=\"\" id=\"62a703b915db00b462264916\" width=\"\"><\/div>\n<p>\u0412\u0438\u0434\u0435\u043e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u043e \u0432 1.5 \u0440\u0430\u0437\u0430.<\/p>\n<h2>\u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c<\/h2>\n<ol>\n<li>\n<p>\u0424\u043e\u0440\u043c\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043c\u0430\u0442\u0447\u0435\u0439 \u0432 Dota 2<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0440\u0435\u043f\u043b\u0435\u0435\u0432<\/p>\n<\/li>\n<li>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043c\u0430\u0442\u0447\u0430<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c DBSCAN<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u0438 \u043f\u043e \u0443\u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u043e\u0434\u0445\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u0441\u044b\u043b\u043a\u0438<\/p>\n<\/li>\n<\/ol>\n<h2>\u0424\u043e\u0440\u043c\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043c\u0430\u0442\u0447\u0435\u0439 \u0432 Dota 2<\/h2>\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u043c\u0430\u0442\u0447\u0430 \u0432 Dota 2 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f Replay \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u0444\u0430\u0439\u043b <code>&lt;match_id>.dem<\/code> \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c protobuf-\u0441\u043e\u0431\u044b\u0442\u0438\u0439: \u043a\u043b\u0438\u043a\u0438, \u0443\u0440\u043e\u043d, \u0445\u0438\u043b, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0447\u0430\u0442 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0441\u0443\u043d\u0443\u0442\u044c \u0444\u0430\u0439\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0438\u0433\u0440\u044b, \u0442\u043e \u043e\u043d \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u0442 \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043c\u0430\u0442\u0447\u0430. \u042d\u0442\u043e \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0438\u0447\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0438\u0432\u043a\u043e \u0438 <s>\u0437\u0430\u043b\u0438\u043f\u043d\u0443\u0442\u044c \u0432 \u0433\u043e\u0434\u043d\u0443\u044e \u043a\u0430\u0442\u043e\u0447\u043a\u0443 \u043f\u043e\u0441\u043b\u0435 \u0442\u044f\u0436\u0435\u043b\u043e\u0433\u043e \u0434\u043d\u044f<\/s> \u0440\u0430\u0441\u043a\u043e\u0432\u044b\u0440\u044f\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0440\u0435\u043f\u043b\u0435\u0435\u0432.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cdb\/365\/1a2\/cdb3651a275e6b65945c371b96d2e4e4.png\" width=\"362\" height=\"335\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cdb\/365\/1a2\/cdb3651a275e6b65945c371b96d2e4e4.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u043e \u043c\u044b \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0440\u043e\u0442\u043e\u0431\u0430\u0444\u044b \u043a\u043e\u0432\u044b\u0440\u044f\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u0443\u043c\u0435\u043b\u044c\u0446\u0435\u0432 \u0438\u0437 \u043a\u043e\u043c\u044c\u044e\u043d\u0438\u0442\u0438 (\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438).<\/p>\n<h2>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0440\u0435\u043f\u043b\u0435\u0435\u0432<\/h2>\n<p>\u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0443\u043c\u0435\u043b\u044c\u0446\u044b \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u043e\u043c \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441 \u0433\u043e\u0432\u043e\u0440\u044f\u0449\u0438\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c Clarity. \u041e\u043d \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Java \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043d\u0430\u0431\u043e\u0440 processor&#8217;\u043e\u0432, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438, \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0432 Docker. \u0421\u043a\u0430\u0447\u0430\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439.<\/p>\n<pre><code class=\"bash\">git clone https:\/\/github.com\/odota\/parser.git<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c Docker.<\/p>\n<pre><code class=\"bash\">sudo service docker start<\/code><\/pre>\n<p>\u0418 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c build-\u0441\u043a\u0440\u0438\u043f\u0442.<\/p>\n<pre><code class=\"bash\">sudo bash parser\/scripts\/rebuild.sh<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u0442\u0443 5600.<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">sudo docker build -t odota\/parser . sudo docker rm -fv parser sudo docker run -d --name parser --net=host odota\/parser<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0423 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043f\u0430\u0440\u0441\u0435\u0440.\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u0435\u043d \u0440\u0435\u043f\u043b\u0435\u0439 \u043c\u0430\u0442\u0447\u0430. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0435\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c.<\/p>\n<p><strong>I. \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438\u0433\u0440\u044b<\/strong><\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0438 \u0447\u0435\u0440\u0435\u0437 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 Watch \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0438\u0433\u0440\u044b. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b<br \/><code>match_id = 6227492909<\/code>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4c8\/8a6\/f42\/4c88a6f42b247f25acccff886b67898d.png\" alt=\"\u0412\u043a\u043b\u0430\u0434\u043a\u0430 Watch \u0432 Dota 2, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0439 \u043f\u043e MatchID\" title=\"\u0412\u043a\u043b\u0430\u0434\u043a\u0430 Watch \u0432 Dota 2, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0439 \u043f\u043e MatchID\" width=\"2287\" height=\"534\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4c8\/8a6\/f42\/4c88a6f42b247f25acccff886b67898d.png\"\/><figcaption>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 Watch \u0432 Dota 2, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0439 \u043f\u043e MatchID<\/figcaption><\/figure>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0438\u0433\u0440\u044b. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0443\u0442\u0438 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430\u0445 \u043f\u043e\u0434 Windows.<\/p>\n<pre><code class=\"bash\">C:\\Program Files (x86)\\Steam\\steamapps\\common\\dota 2 beta\\game\\dota\\replays\\<\/code><\/pre>\n<p><strong>II. \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441 OpenDota<\/strong><\/p>\n<p>\u0415\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0439 \u0441 \u0441\u0430\u0439\u0442\u0430 OpenDota (\u0441\u0441\u044b\u043b\u043a\u0430 \u0432 \u043a\u043e\u0446\u043d\u0435 \u0441\u0442\u0430\u0442\u044c\u0438). \u0420\u0435\u0431\u044f\u0442\u0430 \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u044e\u0442 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0432\u044b\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u044e\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 CDN Valve. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0442\u0434\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u0432 \u0441\u0436\u0430\u0442\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c.<\/p>\n<pre><code class=\"bash\">bzcat replays\/6227492909_1934613958.dem.bz2 > replays\/6227492909.dem<\/code><\/pre>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043c\u044b \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u0441 \u043f\u043e\u0438\u0441\u043a\u043e\u043c <code>.dem<\/code> \u0444\u0430\u0439\u043b\u0430. \u041f\u0440\u043e\u0433\u043e\u043d\u0438\u043c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u0430\u0440\u0441\u0435\u0440.<\/p>\n<pre><code class=\"bash\">curl localhost:5600 --data-binary \"@replays\/6227492909.dem\" > replays\/6227492909.jsonlinesines<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c JSON&#8217;\u044b, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>.jsonlines<\/code>.<\/p>\n<h2>\u0410\u043d\u0430\u043b\u0438\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043c\u0430\u0442\u0447\u0430<\/h2>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0440\u0430\u0441\u0447\u0435\u0445\u043b\u0438\u043c Python \u0438 Jupyter. \u0421\u0447\u0438\u0442\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430 \u0438 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<pre><code class=\"python\">import os import json  REPLAYS_DIR = os.path.join('..\/replays\/')   dem_path = os.path.join(REPLAYS_DIR, '6227492909.jsonlines') with open(dem_path, 'r') as fin:     jsonlines = [json.loads(event) for event in fin.readlines()]      len(jsonlines) > 205385<\/code><\/pre>\n<p>40-\u043c\u0438\u043d\u0443\u0442\u043d\u044b\u0439 \u043c\u0430\u0442\u0447 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0441\u044f \u0432 ~200k \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443.<\/p>\n<pre><code class=\"python\">jsonlines[10] > {'time': -852, 'type': 'player_slot', 'key': '8', 'value': 131}<\/code><\/pre>\n<pre><code class=\"python\">jsonlines[100212]  >  {'time': 1011,  'type': 'DOTA_COMBATLOG_MODIFIER_REMOVE',  'value': 0,  'attackername': 'npc_dota_badguys_tower2_top',  'targetname': 'npc_dota_hero_enchantress',  'sourcename': 'dota_unknown',  'targetsourcename': 'dota_unknown',  'attackerhero': False,  'targethero': True,  'attackerillusion': False,  'targetillusion': False,  'inflictor': 'modifier_tower_aura_bonus'}<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u043b\u044f. \u041d\u043e \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u043f\u043e\u043b\u044f <code>type<\/code> \u2014 \u0442\u0438\u043f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 <code>time<\/code> \u2014 \u0432\u0440\u0435\u043c\u044f \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0430\u0442\u0447\u0430. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e \u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 \u043a\u0440\u0438\u043f\u043e\u0432 (00:00 \u043f\u043e \u0447\u0430\u0441\u0430\u043c \u043c\u0430\u0442\u0447\u0430).<\/p>\n<p>\u041f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<pre><code class=\"python\">from collections import Counter  Counter([e['type'] for e in jsonlines])  > Counter({'DOTA_COMBATLOG_GAME_STATE': 8,          'player_slot': 10,          'interval': 30580,          'draft_start': 1,          'draft_timings': 24,          'actions': 113360,          'CHAT_MESSAGE_ITEM_PURCHASE': 58,          'DOTA_COMBATLOG_GOLD': 2612,          'DOTA_COMBATLOG_MODIFIER_ADD': 7058,          'DOTA_COMBATLOG_PURCHASE': 522,          'DOTA_ABILITY_LEVEL': 406,          'DOTA_COMBATLOG_ABILITY': 1245,          'chatwheel': 22,          'DOTA_COMBATLOG_ITEM': 1658,          'chat': 10,          'DOTA_COMBATLOG_MODIFIER_REMOVE': 7021,          'pings': 482,          'obs': 34,          'DOTA_COMBATLOG_PLAYERSTATS': 225,          'DOTA_COMBATLOG_DAMAGE': 27580,          'DOTA_COMBATLOG_DEATH': 3260,  ...<\/code><\/pre>\n<p>\u042f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043b, \u0447\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0442\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u0433\u0435\u0440\u043e\u0438 \u043d\u0430\u043d\u043e\u0441\u044f\u0442 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443 \u0443\u0440\u043e\u043d. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>DOTA_COMBATLOG_DAMAGE<\/code>. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0440\u043e\u043d\u0430 \u0438\u0433\u0440\u043e\u043a\u0438 \u043d\u0430\u043d\u0435\u0441\u043b\u0438 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443.<\/p>\n<pre><code class=\"python\">import pandas as pd  df_damage = pd.DataFrame([     e for e in jsonlines      if e['type'] == 'DOTA_COMBATLOG_DAMAGE' and     e['attackerhero'] and e['targethero'] ])  df_damage.groupby(['attackername', 'targetname']).agg({'value': 'sum'})<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cab\/e4a\/25d\/cabe4a25d3b24c6b77bbb6124ae7ed9e.png\" alt=\"\u0423\u0440\u043e\u043d \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439 \u0434\u0440\u0443\u0433 \u043f\u043e \u0434\u0440\u0443\u0433\u0443\" title=\"\u0423\u0440\u043e\u043d \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439 \u0434\u0440\u0443\u0433 \u043f\u043e \u0434\u0440\u0443\u0433\u0443\" width=\"455\" height=\"419\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cab\/e4a\/25d\/cabe4a25d3b24c6b77bbb6124ae7ed9e.png\"\/><figcaption>\u0423\u0440\u043e\u043d \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439 \u0434\u0440\u0443\u0433 \u043f\u043e \u0434\u0440\u0443\u0433\u0443<\/figcaption><\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u044f \u0441\u0440\u0430\u0432\u043d\u0438\u043b \u0441 \u0432\u044b\u0432\u043e\u0434\u0430\u043c\u0438 \u043d\u0430 \u0432\u0441\u0435 \u0442\u043e\u043c \u0436\u0435 \u0441\u0430\u0439\u0442\u0435 OpenDota \u0438 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u0435\u043d, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043e\u0432\u043f\u0430\u043b\u0438.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u0438\u0433\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0430\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0433\u0435\u0440\u043e\u0439 Magnus \u0432 \u0440\u0435\u043f\u043b\u0435\u044f\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u043e\u0434\u043e\u0432\u043e\u0435 \u0438\u043c\u044f <code>npc_dota_hero_magnataur<\/code>.<\/p>\n<pre><code class=\"python\">df_damage['attackername'].unique()  > array(['npc_dota_hero_ember_spirit', 'npc_dota_hero_kunkka',        'npc_dota_hero_enchantress', 'npc_dota_hero_bane',        'npc_dota_hero_tiny', 'npc_dota_hero_magnataur',        'npc_dota_hero_lycan', 'npc_dota_hero_skywrath_mage',        'npc_dota_hero_winter_wyvern', 'npc_dota_hero_terrorblade'],       dtype=object)<\/code><\/pre>\n<p>\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u0439\u043c\u043b\u0430\u0439\u043d \u0443\u0440\u043e\u043d\u0430 \u043e\u0442 \u0438\u0433\u0440\u043e\u043a\u0430 Collapse \u043d\u0430 Magnus \u043f\u043e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430\u043c \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432.<\/p>\n<pre><code class=\"python\">import matplotlib.pyplot as plt  mask = df_damage['attackername'] == 'npc_dota_hero_magnataur' df_player_damage = df_damage[mask].copy() df_player_damage['ones'] = 1  fig, ax = plt.subplots(figsize=(19, 5)) plt.scatter(     x=df_player_damage['time'] \/ 60,      y=df_player_damage['ones'] ) plt.plot()<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1fe\/104\/153\/1fe1041533c68c98cda7cc4aab6b70f8.png\" alt=\"\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043d\u0430 Magnus \u043f\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u043e \u043c\u0438\u043d\u0443\u0442\u0430\u043c \u043c\u0430\u0442\u0447\u0430\" title=\"\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043d\u0430 Magnus \u043f\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u043e \u043c\u0438\u043d\u0443\u0442\u0430\u043c \u043c\u0430\u0442\u0447\u0430\" width=\"1100\" height=\"299\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1fe\/104\/153\/1fe1041533c68c98cda7cc4aab6b70f8.png\"\/><figcaption>\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043d\u0430 Magnus \u043f\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u043e \u043c\u0438\u043d\u0443\u0442\u0430\u043c \u043c\u0430\u0442\u0447\u0430<\/figcaption><\/figure>\n<p>\u041c\u0430\u0442\u0447\u0438 \u0432 Dota 2 \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 2 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0441\u0442\u0430\u0434\u0438\u0438: \u043b\u0430\u0439\u043d\u0438\u043d\u0433 \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 Collapse \u044d\u0442\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0433\u0440\u0430\u043d\u0438\u0446\u0435 ~10 \u043c\u0438\u043d\u0443\u0442 \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0445\u043e\u0434\u0430 \u043a\u0440\u0438\u043f\u043e\u0432. \u0413\u0435\u0440\u043e\u0439 Magnus \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0440\u0430\u0437 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 \u0437\u0430 \u0441\u0447\u0435\u0442 \u043f\u043e\u043a\u0443\u043f\u043a\u0438 Blink Dagger \u0438 \u043e\u0431\u0438\u043b\u0438\u044f \u043c\u0430\u0441\u0441\u043e\u0432\u044b\u0445 \u0434\u0440\u0430\u043a. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0441\u0435\u0447\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e 10 \u043c\u0438\u043d\u0443\u0442\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u043e\u0447\u0435\u043a \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u043d\u0430.<\/p>\n<pre><code class=\"python\">df_player_late_damage = df_player_damage[df_player_damage['time'] > 10 * 60].copy()  fig, ax = plt.subplots(figsize=(19, 5)) plt.scatter(     x=df_player_late_damage['time'] \/ 60,      y=df_player_late_damage['ones'],      s=df_player_late_damage['value'] ) plt.plot()<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ed2\/ee9\/abf\/ed2ee9abf66aa09b044b092f4156d399.png\" alt=\"\u0423\u0440\u043e\u043d \u043e\u0442 Magnus \u043f\u043e \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 10-\u0439 \u043c\u0438\u043d\u0443\u0442\u044b \u043c\u0430\u0442\u0447\u0430\" title=\"\u0423\u0440\u043e\u043d \u043e\u0442 Magnus \u043f\u043e \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 10-\u0439 \u043c\u0438\u043d\u0443\u0442\u044b \u043c\u0430\u0442\u0447\u0430\" width=\"1109\" height=\"301\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ed2\/ee9\/abf\/ed2ee9abf66aa09b044b092f4156d399.png\"\/><figcaption>\u0423\u0440\u043e\u043d \u043e\u0442 Magnus \u043f\u043e \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 10-\u0439 \u043c\u0438\u043d\u0443\u0442\u044b \u043c\u0430\u0442\u0447\u0430<\/figcaption><\/figure>\n<h2>\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c DBSCAN<\/h2>\n<p>\u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043e\u0449\u0443\u0442\u0438\u043c\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436 \u043d\u0435 \u043d\u0430\u043d\u043e\u0441\u0438\u0442 \u0443\u0440\u043e\u043d. \u0410 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438 \u0448\u0430\u043d\u0441\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u044b \u0432 \u044d\u0442\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043a\u0440\u0430\u0439\u043d\u0435 \u043d\u0435\u0432\u0435\u043b\u0438\u043a\u0438. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043d\u0430 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043b\u043e\u0442\u043d\u044b\u0435 \u0433\u0440\u0443\u043f\u043f\u044b. \u0418\u043d\u0442\u0443\u0438\u0446\u0438\u044f \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u044d\u0442\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u0435\u0441\u0442\u044c \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0438\u043f\u044b \u0441 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438. \u0412\u0441\u0435 \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u2014 \u043d\u0430\u0439\u0442\u0438 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u043f\u0430.<\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u0435\u0441\u0442\u0438 \u043a \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u2014 \u043c\u0435\u0442\u043e\u0434\u0443 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u0443\u0447\u0438\u0442\u0435\u043b\u044f, \u0433\u0434\u0435 \u043e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u043d\u0430 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u2014 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u044b.<\/p>\n<p>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043d\u043e\u0433\u043e, \u043d\u0438\u0436\u0435 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0437 \u043d\u0438\u0445 \u043d\u0430 \u0441\u0438\u043d\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0bd\/880\/10c\/0bd88010ce5c67a3731d07727b41b87b.png\" alt=\"\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 scikit-learn \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a: https:\/\/scikit-learn.org\/stable\/modules\/clustering.html\" title=\"\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 scikit-learn \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a: https:\/\/scikit-learn.org\/stable\/modules\/clustering.html\" width=\"2100\" height=\"1300\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0bd\/880\/10c\/0bd88010ce5c67a3731d07727b41b87b.png\"\/><figcaption>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 scikit-learn \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a: https:\/\/scikit-learn.org\/stable\/modules\/clustering.html<\/figcaption><\/figure>\n<p>\u041c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c DBSCAN. \u0421\u0443\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0430: \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\epsilon\" alt=\"\\epsilon\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7e0\/c73\/623\/7e0c73623cadf5f4ce192c1b0566e2cf.svg\" width=\"8\" height=\"12\"\/>&#8212; \u043e\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430. \u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0442\u0440\u0438\u043a, \u043d\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0445\u0432\u0430\u0442\u0438\u0442 \u0441\u0430\u043c\u043e\u0439 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0439 \u2014 \u0415\u0432\u043a\u043b\u0438\u0434\u043e\u0432\u043e\u0439.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"d(p,q) = \\sqrt{(p_1 - q_1)^2 + ... + (p_n - q_n)^2}\" alt=\"d(p,q) = \\sqrt{(p_1 - q_1)^2 + ... + (p_n - q_n)^2}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b34\/5bc\/d01\/b345bcd018076ad72648a66b27ccd541.svg\" width=\"322\" height=\"39\"\/><\/p>\n<p>\u041f\u0440\u0438\u0447\u0435\u043c \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u043d\u0430, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0422.\u0435. \u0434\u043b\u044f <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\epsilon = 30\" alt=\"\\epsilon = 30\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9d9\/9d6\/350\/9d99d6350a94113901d2ef1315b73178.svg\" width=\"53\" height=\"16\"\/>\u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 ~30 \u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>\u0412\u0442\u043e\u0440\u044b\u043c \u0432\u0430\u0436\u043d\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>min_samples<\/code>. \u041e\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445. \u0415\u0441\u043b\u0438 \u0432\u043e\u043a\u0440\u0443\u0433 \u0442\u043e\u0447\u043a\u0438 \u043c\u0430\u043b\u043e \u0441\u043e\u0441\u0435\u0434\u0435\u0439, \u0442\u043e \u0435\u0439 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043a\u0430 <code>-1<\/code> \u2014 \u0432\u044b\u0431\u0440\u043e\u0441. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c <code>min_samples = 1<\/code> \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043a\u043b\u0438\u043f\u0430\u043c \u0441 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0447\u0430\u043b\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u043a\u043e\u043d\u0446\u043e\u043c.<\/p>\n<pre><code class=\"python\">from sklearn.cluster import DBSCAN  dbscan = DBSCAN(eps=30, min_samples=2) cluster = dbscan.fit_predict(df_player_late_damage[['time', 'ones']]) df_player_late_damage['cluster'] = cluster  fig, ax = plt.subplots(figsize=(19, 5)) plt.scatter(     x=df_player_late_damage['time'] \/ 60,      y=df_player_late_damage['ones'],      s=df_player_late_damage['value'],     c=df_player_late_damage['cluster'] )<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f22\/b07\/1b3\/f22b071b3e8d438d027ff4a5169fc1aa.png\" alt=\"\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0443\u0440\u043e\u043d \u043e\u0442 Magnus\" title=\"\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0443\u0440\u043e\u043d \u043e\u0442 Magnus\" width=\"1106\" height=\"300\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f22\/b07\/1b3\/f22b071b3e8d438d027ff4a5169fc1aa.png\"\/><figcaption>\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0443\u0440\u043e\u043d \u043e\u0442 Magnus<\/figcaption><\/figure>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u044b \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438 \u043c\u0430\u0442\u0447\u0430. \u0414\u043b\u044f \u043d\u0430\u0440\u0435\u0437\u043a\u0438 \u043a\u043b\u0438\u043f\u043e\u0432 \u0441 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438 \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u043a\u0430\u0436\u0434\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430.<\/p>\n<pre><code class=\"python\">df_player_late_damage['stime'] = df_player_late_damage['time'].apply(     lambda t: f'{t \/\/ 60}:{str(t % 60).zfill(2)}') df_action = df_player_late_damage.groupby('cluster').agg({'stime': ['first', 'last']}) df_action.sort_values(('stime', 'first'))<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5de\/06b\/dd6\/5de06bdd6ee7f7ec710d38d05c19fbcb.png\" width=\"143\" height=\"385\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5de\/06b\/dd6\/5de06bdd6ee7f7ec710d38d05c19fbcb.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0423\u0441\u043f\u0435\u0445! \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0438\u0447\u0435\u0439 \u0438\u0433\u0440\u044b \u0438 \u043d\u0430\u0440\u0435\u0437\u0430\u0442\u044c \u043a\u043b\u0438\u043f\u044b. \u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0432\u0438\u0434\u0435\u043e \u0432\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<h2>\u0418\u0434\u0435\u0438 \u043f\u043e \u0443\u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u043e\u0434\u0445\u043e\u0434\u0430<\/h2>\n<ol>\n<li>\n<p>\u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u043c\u0435\u0442\u0438\u0442, \u0447\u0442\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0442\u044e\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0438\u043b\u0438 \u0432\u043e\u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u043e\u0432 \u0441 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u043c\u0438. \u041a\u0430\u043a \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438 \u043f\u043e \u044d\u043f\u0438\u0447\u043d\u043e\u0441\u0442\u0438?<br \/>\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u0440\u043e\u043d\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432\u0438\u0434\u0435\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442 \u0438\u0433\u0440\u044b \u0438 \u043d\u0430\u043a\u043b\u0438\u043a\u0438\u0432\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438?<br \/>\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>demo_goto<\/code>, <code>demo_gototick<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435. \u0418\u0441\u043a\u0443\u0448\u0435\u043d\u043d\u044b\u0445 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u044e \u043e\u0431\u0441\u0443\u0434\u0438\u0442\u044c <s>MMR \u0430\u0432\u0442\u043e\u0440\u0430<\/s> \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445.<\/p>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0438<\/h2>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/SteamDatabase\/GameTracking-Dota2\" rel=\"noopener noreferrer nofollow\">\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 protobuf<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/skadistats\/clarity\" rel=\"noopener noreferrer nofollow\">Clarity<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/odota\/parser\" rel=\"noopener noreferrer nofollow\">Fork Clarity \u043e\u0442 OpenDota<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.opendota.com\/matches\/6227492909\/overview\" rel=\"noopener noreferrer nofollow\">\u041c\u0430\u0442\u0447 Team Spirit vs PSG.LGD \u043d\u0430 OpenDota<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"http:\/\/replay273.valve.net\/570\/6227492909_1934613958.dem.bz2\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043b\u0435\u0439<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/scikit-learn.org\/stable\/modules\/clustering.html#dbscan\" rel=\"noopener noreferrer nofollow\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 DBSCAN<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.cluster.DBSCAN.html\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e DBSCAN \u0432 scikit-learn<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.metrics.pairwise_distances.html#sklearn.metrics.pairwise_distances\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043c\u0435\u0442\u0440\u0438\u043a<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/672420\/\"> https:\/\/habr.com\/ru\/post\/672420\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0432 Dota 2 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0440\u0435\u0437\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e-\u0440\u043e\u043b\u0438\u043a\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>.mp4<\/code> \u043f\u0440\u0438 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043c\u0430\u0442\u0447\u0435\u0439. \u042f \u043d\u0435 \u0443\u0434\u0435\u0440\u0436\u0430\u043b\u0441\u044f \u0438 \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 aka \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432. \u0412\u043e\u0442 \u0447\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043a\u0430\u0440\u0442\u044b \u0433\u0440\u0430\u043d\u0434-\u0444\u0438\u043d\u0430\u043b\u0430 The International 2021, \u0433\u0434\u0435 Collapse \u0438\u0437 Team Spirit \u043a\u0430\u0442\u0430\u043b PSG.LGD \u043d\u0430 \u0441\u0432\u043e\u0435\u043c Magnus&#8217;\u0435.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/62a703b915db00b462264916\" data-style=\"\" id=\"62a703b915db00b462264916\" width=\"\"><\/div>\n<p>\u0412\u0438\u0434\u0435\u043e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u043e \u0432 1.5 \u0440\u0430\u0437\u0430.<\/p>\n<h2>\u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c<\/h2>\n<ol>\n<li>\n<p>\u0424\u043e\u0440\u043c\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043c\u0430\u0442\u0447\u0435\u0439 \u0432 Dota 2<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0440\u0435\u043f\u043b\u0435\u0435\u0432<\/p>\n<\/li>\n<li>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043c\u0430\u0442\u0447\u0430<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c DBSCAN<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u0438 \u043f\u043e \u0443\u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u043e\u0434\u0445\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u0441\u044b\u043b\u043a\u0438<\/p>\n<\/li>\n<\/ol>\n<h2>\u0424\u043e\u0440\u043c\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043c\u0430\u0442\u0447\u0435\u0439 \u0432 Dota 2<\/h2>\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u043c\u0430\u0442\u0447\u0430 \u0432 Dota 2 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f Replay \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u0444\u0430\u0439\u043b <code>&lt;match_id>.dem<\/code> \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c protobuf-\u0441\u043e\u0431\u044b\u0442\u0438\u0439: \u043a\u043b\u0438\u043a\u0438, \u0443\u0440\u043e\u043d, \u0445\u0438\u043b, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0447\u0430\u0442 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0441\u0443\u043d\u0443\u0442\u044c \u0444\u0430\u0439\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0438\u0433\u0440\u044b, \u0442\u043e \u043e\u043d \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u0442 \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043c\u0430\u0442\u0447\u0430. \u042d\u0442\u043e \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0438\u0447\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0438\u0432\u043a\u043e \u0438 <s>\u0437\u0430\u043b\u0438\u043f\u043d\u0443\u0442\u044c \u0432 \u0433\u043e\u0434\u043d\u0443\u044e \u043a\u0430\u0442\u043e\u0447\u043a\u0443 \u043f\u043e\u0441\u043b\u0435 \u0442\u044f\u0436\u0435\u043b\u043e\u0433\u043e \u0434\u043d\u044f<\/s> \u0440\u0430\u0441\u043a\u043e\u0432\u044b\u0440\u044f\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0440\u0435\u043f\u043b\u0435\u0435\u0432.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u043e \u043c\u044b \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0440\u043e\u0442\u043e\u0431\u0430\u0444\u044b \u043a\u043e\u0432\u044b\u0440\u044f\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u0443\u043c\u0435\u043b\u044c\u0446\u0435\u0432 \u0438\u0437 \u043a\u043e\u043c\u044c\u044e\u043d\u0438\u0442\u0438 (\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438).<\/p>\n<h2>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0440\u0435\u043f\u043b\u0435\u0435\u0432<\/h2>\n<p>\u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0443\u043c\u0435\u043b\u044c\u0446\u044b \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u043e\u043c \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441 \u0433\u043e\u0432\u043e\u0440\u044f\u0449\u0438\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c Clarity. \u041e\u043d \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Java \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043d\u0430\u0431\u043e\u0440 processor&#8217;\u043e\u0432, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438, \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0432 Docker. \u0421\u043a\u0430\u0447\u0430\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439.<\/p>\n<pre><code class=\"bash\">git clone https:\/\/github.com\/odota\/parser.git<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c Docker.<\/p>\n<pre><code class=\"bash\">sudo service docker start<\/code><\/pre>\n<p>\u0418 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c build-\u0441\u043a\u0440\u0438\u043f\u0442.<\/p>\n<pre><code class=\"bash\">sudo bash parser\/scripts\/rebuild.sh<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u0442\u0443 5600.<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">sudo docker build -t odota\/parser . sudo docker rm -fv parser sudo docker run -d --name parser --net=host odota\/parser<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0423 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043f\u0430\u0440\u0441\u0435\u0440.\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u0435\u043d \u0440\u0435\u043f\u043b\u0435\u0439 \u043c\u0430\u0442\u0447\u0430. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0435\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c.<\/p>\n<p><strong>I. \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438\u0433\u0440\u044b<\/strong><\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0438 \u0447\u0435\u0440\u0435\u0437 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 Watch \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0438\u0433\u0440\u044b. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b<br \/><code>match_id = 6227492909<\/code>.<\/p>\n<figure class=\"full-width\"><figcaption>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 Watch \u0432 Dota 2, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0439 \u043f\u043e MatchID<\/figcaption><\/figure>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0438\u0433\u0440\u044b. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0443\u0442\u0438 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430\u0445 \u043f\u043e\u0434 Windows.<\/p>\n<pre><code class=\"bash\">C:\\Program Files (x86)\\Steam\\steamapps\\common\\dota 2 beta\\game\\dota\\replays\\<\/code><\/pre>\n<p><strong>II. \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441 OpenDota<\/strong><\/p>\n<p>\u0415\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0439 \u0441 \u0441\u0430\u0439\u0442\u0430 OpenDota (\u0441\u0441\u044b\u043b\u043a\u0430 \u0432 \u043a\u043e\u0446\u043d\u0435 \u0441\u0442\u0430\u0442\u044c\u0438). \u0420\u0435\u0431\u044f\u0442\u0430 \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u044e\u0442 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0432\u044b\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u044e\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 CDN Valve. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0442\u0434\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u0432 \u0441\u0436\u0430\u0442\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c.<\/p>\n<pre><code class=\"bash\">bzcat replays\/6227492909_1934613958.dem.bz2 > replays\/6227492909.dem<\/code><\/pre>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043c\u044b \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u0441 \u043f\u043e\u0438\u0441\u043a\u043e\u043c <code>.dem<\/code> \u0444\u0430\u0439\u043b\u0430. \u041f\u0440\u043e\u0433\u043e\u043d\u0438\u043c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u0430\u0440\u0441\u0435\u0440.<\/p>\n<pre><code class=\"bash\">curl localhost:5600 --data-binary \"@replays\/6227492909.dem\" > replays\/6227492909.jsonlinesines<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c JSON&#8217;\u044b, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>.jsonlines<\/code>.<\/p>\n<h2>\u0410\u043d\u0430\u043b\u0438\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043c\u0430\u0442\u0447\u0430<\/h2>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0440\u0430\u0441\u0447\u0435\u0445\u043b\u0438\u043c Python \u0438 Jupyter. \u0421\u0447\u0438\u0442\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430 \u0438 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<pre><code class=\"python\">import os import json  REPLAYS_DIR = os.path.join('..\/replays\/')   dem_path = os.path.join(REPLAYS_DIR, '6227492909.jsonlines') with open(dem_path, 'r') as fin:     jsonlines = [json.loads(event) for event in fin.readlines()]      len(jsonlines) > 205385<\/code><\/pre>\n<p>40-\u043c\u0438\u043d\u0443\u0442\u043d\u044b\u0439 \u043c\u0430\u0442\u0447 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0441\u044f \u0432 ~200k \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443.<\/p>\n<pre><code class=\"python\">jsonlines[10] > {'time': -852, 'type': 'player_slot', 'key': '8', 'value': 131}<\/code><\/pre>\n<pre><code class=\"python\">jsonlines[100212]  >  {'time': 1011,  'type': 'DOTA_COMBATLOG_MODIFIER_REMOVE',  'value': 0,  'attackername': 'npc_dota_badguys_tower2_top',  'targetname': 'npc_dota_hero_enchantress',  'sourcename': 'dota_unknown',  'targetsourcename': 'dota_unknown',  'attackerhero': False,  'targethero': True,  'attackerillusion': False,  'targetillusion': False,  'inflictor': 'modifier_tower_aura_bonus'}<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u043b\u044f. \u041d\u043e \u0432\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u043f\u043e\u043b\u044f <code>type<\/code> \u2014 \u0442\u0438\u043f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 <code>time<\/code> \u2014 \u0432\u0440\u0435\u043c\u044f \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0430\u0442\u0447\u0430. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e \u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 \u043a\u0440\u0438\u043f\u043e\u0432 (00:00 \u043f\u043e \u0447\u0430\u0441\u0430\u043c \u043c\u0430\u0442\u0447\u0430).<\/p>\n<p>\u041f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<pre><code class=\"python\">from collections import Counter  Counter([e['type'] for e in jsonlines])  > Counter({'DOTA_COMBATLOG_GAME_STATE': 8,          'player_slot': 10,          'interval': 30580,          'draft_start': 1,          'draft_timings': 24,          'actions': 113360,          'CHAT_MESSAGE_ITEM_PURCHASE': 58,          'DOTA_COMBATLOG_GOLD': 2612,          'DOTA_COMBATLOG_MODIFIER_ADD': 7058,          'DOTA_COMBATLOG_PURCHASE': 522,          'DOTA_ABILITY_LEVEL': 406,          'DOTA_COMBATLOG_ABILITY': 1245,          'chatwheel': 22,          'DOTA_COMBATLOG_ITEM': 1658,          'chat': 10,          'DOTA_COMBATLOG_MODIFIER_REMOVE': 7021,          'pings': 482,          'obs': 34,          'DOTA_COMBATLOG_PLAYERSTATS': 225,          'DOTA_COMBATLOG_DAMAGE': 27580,          'DOTA_COMBATLOG_DEATH': 3260,  ...<\/code><\/pre>\n<p>\u042f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043b, \u0447\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0442\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u0433\u0435\u0440\u043e\u0438 \u043d\u0430\u043d\u043e\u0441\u044f\u0442 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443 \u0443\u0440\u043e\u043d. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>DOTA_COMBATLOG_DAMAGE<\/code>. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0440\u043e\u043d\u0430 \u0438\u0433\u0440\u043e\u043a\u0438 \u043d\u0430\u043d\u0435\u0441\u043b\u0438 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443.<\/p>\n<pre><code class=\"python\">import pandas as pd  df_damage = pd.DataFrame([     e for e in jsonlines      if e['type'] == 'DOTA_COMBATLOG_DAMAGE' and     e['attackerhero'] and e['targethero'] ])  df_damage.groupby(['attackername', 'targetname']).agg({'value': 'sum'})<\/code><\/pre>\n<figure class=\"\"><figcaption>\u0423\u0440\u043e\u043d \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439 \u0434\u0440\u0443\u0433 \u043f\u043e \u0434\u0440\u0443\u0433\u0443<\/figcaption><\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u044f \u0441\u0440\u0430\u0432\u043d\u0438\u043b \u0441 \u0432\u044b\u0432\u043e\u0434\u0430\u043c\u0438 \u043d\u0430 \u0432\u0441\u0435 \u0442\u043e\u043c \u0436\u0435 \u0441\u0430\u0439\u0442\u0435 OpenDota \u0438 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u0435\u043d, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043e\u0432\u043f\u0430\u043b\u0438.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u0438\u0433\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0430\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0433\u0435\u0440\u043e\u0439 Magnus \u0432 \u0440\u0435\u043f\u043b\u0435\u044f\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u043e\u0434\u043e\u0432\u043e\u0435 \u0438\u043c\u044f <code>npc_dota_hero_magnataur<\/code>.<\/p>\n<pre><code class=\"python\">df_damage['attackername'].unique()  > array(['npc_dota_hero_ember_spirit', 'npc_dota_hero_kunkka',        'npc_dota_hero_enchantress', 'npc_dota_hero_bane',        'npc_dota_hero_tiny', 'npc_dota_hero_magnataur',        'npc_dota_hero_lycan', 'npc_dota_hero_skywrath_mage',        'npc_dota_hero_winter_wyvern', 'npc_dota_hero_terrorblade'],       dtype=object)<\/code><\/pre>\n<p>\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u0439\u043c\u043b\u0430\u0439\u043d \u0443\u0440\u043e\u043d\u0430 \u043e\u0442 \u0438\u0433\u0440\u043e\u043a\u0430 Collapse \u043d\u0430 Magnus \u043f\u043e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430\u043c \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432.<\/p>\n<pre><code class=\"python\">import matplotlib.pyplot as plt  mask = df_damage['attackername'] == 'npc_dota_hero_magnataur' df_player_damage = df_damage[mask].copy() df_player_damage['ones'] = 1  fig, ax = plt.subplots(figsize=(19, 5)) plt.scatter(     x=df_player_damage['time'] \/ 60,      y=df_player_damage['ones'] ) plt.plot()<\/code><\/pre>\n<figure class=\"full-width\"><figcaption>\u0421\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043d\u0430 Magnus \u043f\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u043e \u043c\u0438\u043d\u0443\u0442\u0430\u043c \u043c\u0430\u0442\u0447\u0430<\/figcaption><\/figure>\n<p>\u041c\u0430\u0442\u0447\u0438 \u0432 Dota 2 \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 2 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0441\u0442\u0430\u0434\u0438\u0438: \u043b\u0430\u0439\u043d\u0438\u043d\u0433 \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 Collapse \u044d\u0442\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0433\u0440\u0430\u043d\u0438\u0446\u0435 ~10 \u043c\u0438\u043d\u0443\u0442 \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0445\u043e\u0434\u0430 \u043a\u0440\u0438\u043f\u043e\u0432. \u0413\u0435\u0440\u043e\u0439 Magnus \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0440\u0430\u0437 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 \u0437\u0430 \u0441\u0447\u0435\u0442 \u043f\u043e\u043a\u0443\u043f\u043a\u0438 Blink Dagger \u0438 \u043e\u0431\u0438\u043b\u0438\u044f \u043c\u0430\u0441\u0441\u043e\u0432\u044b\u0445 \u0434\u0440\u0430\u043a. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0441\u0435\u0447\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e 10 \u043c\u0438\u043d\u0443\u0442\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u043e\u0447\u0435\u043a \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u043d\u0430.<\/p>\n<pre><code class=\"python\">df_player_late_damage = df_player_damage[df_player_damage['time'] > 10 * 60].copy()  fig, ax = plt.subplots(figsize=(19, 5)) plt.scatter(     x=df_player_late_damage['time'] \/ 60,      y=df_player_late_damage['ones'],      s=df_player_late_damage['value'] ) plt.plot()<\/code><\/pre>\n<figure class=\"full-width\"><figcaption>\u0423\u0440\u043e\u043d \u043e\u0442 Magnus \u043f\u043e \u0433\u0435\u0440\u043e\u044f\u043c \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 10-\u0439 \u043c\u0438\u043d\u0443\u0442\u044b \u043c\u0430\u0442\u0447\u0430<\/figcaption><\/figure>\n<h2>\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c DBSCAN<\/h2>\n<p>\u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043e\u0449\u0443\u0442\u0438\u043c\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436 \u043d\u0435 \u043d\u0430\u043d\u043e\u0441\u0438\u0442 \u0443\u0440\u043e\u043d. \u0410 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438 \u0448\u0430\u043d\u0441\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u044b \u0432 \u044d\u0442\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043a\u0440\u0430\u0439\u043d\u0435 \u043d\u0435\u0432\u0435\u043b\u0438\u043a\u0438. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u043d\u0430 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043b\u043e\u0442\u043d\u044b\u0435 \u0433\u0440\u0443\u043f\u043f\u044b. \u0418\u043d\u0442\u0443\u0438\u0446\u0438\u044f \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u044d\u0442\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u0435\u0441\u0442\u044c \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0438\u043f\u044b \u0441 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438. \u0412\u0441\u0435 \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u2014 \u043d\u0430\u0439\u0442\u0438 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u043f\u0430.<\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u0435\u0441\u0442\u0438 \u043a \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u2014 \u043c\u0435\u0442\u043e\u0434\u0443 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u0443\u0447\u0438\u0442\u0435\u043b\u044f, \u0433\u0434\u0435 \u043e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u043d\u0430 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u2014 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u044b.<\/p>\n<p>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043d\u043e\u0433\u043e, \u043d\u0438\u0436\u0435 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0437 \u043d\u0438\u0445 \u043d\u0430 \u0441\u0438\u043d\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<figure class=\"full-width\"><figcaption>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 scikit-learn \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a: https:\/\/scikit-learn.org\/stable\/modules\/clustering.html<\/figcaption><\/figure>\n<p>\u041c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c DBSCAN. \u0421\u0443\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0430: \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f &#8212; \u043e\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430. \u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0442\u0440\u0438\u043a, \u043d\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0445\u0432\u0430\u0442\u0438\u0442 \u0441\u0430\u043c\u043e\u0439 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0439 \u2014 \u0415\u0432\u043a\u043b\u0438\u0434\u043e\u0432\u043e\u0439.<\/p>\n<p>\u041f\u0440\u0438\u0447\u0435\u043c \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u043d\u0430, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0422.\u0435. \u0434\u043b\u044f \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 ~30 \u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>\u0412\u0442\u043e\u0440\u044b\u043c \u0432\u0430\u0436\u043d\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>min_samples<\/code>. \u041e\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445. \u0415\u0441\u043b\u0438 \u0432\u043e\u043a\u0440\u0443\u0433 \u0442\u043e\u0447\u043a\u0438 \u043c\u0430\u043b\u043e \u0441\u043e\u0441\u0435\u0434\u0435\u0439, \u0442\u043e \u0435\u0439 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043a\u0430 <code>-1<\/code> \u2014 \u0432\u044b\u0431\u0440\u043e\u0441. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c <code>min_samples = 1<\/code> \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043a\u043b\u0438\u043f\u0430\u043c \u0441 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0447\u0430\u043b\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u043a\u043e\u043d\u0446\u043e\u043c.<\/p>\n<pre><code class=\"python\">from sklearn.cluster import DBSCAN  dbscan = DBSCAN(eps=30, min_samples=2) cluster = dbscan.fit_predict(df_player_late_damage[['time', 'ones']]) df_player_late_damage['cluster'] = cluster  fig, ax = plt.subplots(figsize=(19, 5)) plt.scatter(     x=df_player_late_damage['time'] \/ 60,      y=df_player_late_damage['ones'],      s=df_player_late_damage['value'],     c=df_player_late_damage['cluster'] )<\/code><\/pre>\n<figure class=\"full-width\"><figcaption>\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0443\u0440\u043e\u043d \u043e\u0442 Magnus<\/figcaption><\/figure>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u044b \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438 \u043c\u0430\u0442\u0447\u0430. \u0414\u043b\u044f \u043d\u0430\u0440\u0435\u0437\u043a\u0438 \u043a\u043b\u0438\u043f\u043e\u0432 \u0441 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438 \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u043a\u0430\u0436\u0434\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430.<\/p>\n<pre><code class=\"python\">df_player_late_damage['stime'] = df_player_late_damage['time'].apply(     lambda t: f'{t \/\/ 60}:{str(t % 60).zfill(2)}') df_action = df_player_late_damage.groupby('cluster').agg({'stime': ['first', 'last']}) df_action.sort_values(('stime', 'first'))<\/code><\/pre>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0423\u0441\u043f\u0435\u0445! \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0438\u0447\u0435\u0439 \u0438\u0433\u0440\u044b \u0438 \u043d\u0430\u0440\u0435\u0437\u0430\u0442\u044c \u043a\u043b\u0438\u043f\u044b. \u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0432\u0438\u0434\u0435\u043e \u0432\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<h2>\u0418\u0434\u0435\u0438 \u043f\u043e \u0443\u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u043e\u0434\u0445\u043e\u0434\u0430<\/h2>\n<ol>\n<li>\n<p>\u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u043c\u0435\u0442\u0438\u0442, \u0447\u0442\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0442\u044e\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0438\u043b\u0438 \u0432\u043e\u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u043e\u0432 \u0441 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u043c\u0438. \u041a\u0430\u043a \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438 \u043f\u043e \u044d\u043f\u0438\u0447\u043d\u043e\u0441\u0442\u0438?<br \/>\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: <\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-334743","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334743","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=334743"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334743\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=334743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=334743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=334743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}