Trước khi có thể làm việc với dữ liệu, việc đầu tiên bạn cần làm là thu thập chúng. Có rất nhiều nguồn dữ liệu khác nhau như web, APIs, databases, những định dạng file plain text (.csv, .tsv). Sau khi thu thập, ta có thể thực hiện vài động tác chuẩn hoá dữ liệu sao cho phù hợp với nhu cầu làm việc của mình nhất.
Tiếp tục series Python snippet (Python snippet: Visualizing), tuần này tôi sẽ đưa vào một vài snippet thường gặp trong quá trình thu thập dữ liệu.
Source code: data-science-works
Thư viện: csv, json, re, collections, requests, bs4, twython
TSV
TSV là viết tắt của Tab Separated Values. Đây là định dạng file trong đó dữ liệu ngăn cách nhau bởi ký tự Tab. Ví dụ bên dưới sẽ đọc vào một file .tsv và xuất dữ liệu ra ngoài màn hình.
Input: tab_delimited_stock_prices.tsv
Nguồn thu thập: http://s.cafef.vn/du-lieu.chn
Snippet:
import csv def print_data(ma_ck, kl, gia, delta): print ma_ck, "#", kl, "#", gia, "#", delta with open('data/tab_delimited_stock_prices.tsv', 'rb') as f: reader = csv.reader(f, delimiter='\t') for row in reader: ma_ck = row[0] kl = row[1] gia = float(row[2]) delta = row[3] print_data(ma_ck, kl, gia, delta)
Output:
## TAB delimited stock prices TV2 # 45,012 # 147.4 # +13.4 (+10.00%) CTT # 100 # 6.6 # +0.6 (+10.00%) PCE # 100 # 16.6 # +1.5 (+9.93%) HAT # 13,300 # 73.2 # +6.6 (+9.87%)
CSV
CSV là viết tắt của Colon/Comma Separated Values. Đây là định dạng file trong đó dữ liệu ngăn cách nhau bởi ký tự “:” hoặc “,”. Ví dụ bên dưới sẽ đọc vào một file .csv và xuất dữ liệu ra ngoài màn hình hoặc một file .csv khác.
Input: colon_delimited_stock_prices.csv
Nguồn thu thập: http://s.cafef.vn/du-lieu.chn
Snippet:
import csv def print_data(ma_ck, kl, gia, delta): print ma_ck, "#", kl, "#", gia, "#", delta with open('data/colon_delimited_stock_prices.csv', 'rb') as f: reader = csv.DictReader(f, delimiter=':') for row in reader: ma_ck = row["MA_CK"] kl = row["KL"] gia = float(row["GIA"]) delta = row["DELTA"] print_data(ma_ck, kl, gia, delta) print "## WRITING out comma_delimited_stock_prices.csv" today_prices = {'VCF': 152.4, 'VAF': 13.3, 'ATA': 0.8} with open('data/comma_delimited_stock_prices.csv', 'wb') as f: writer = csv.writer(f, delimiter=',') for stock, price in today_prices.items(): writer.writerow([stock, price])
Output: comma_delimited_stock_prices.csv
## COLON delimited stock prices TV2 # 45,012 # 147.4 # +13.4 (+10.00%) CTT # 100 # 6.6 # +0.6 (+10.00%) PCE # 100 # 16.6 # +1.5 (+9.93%) HAT # 13,300 # 73.2 # +6.6 (+9.87%)
JSON
JSON là viết tắt của JavaScript Object Notation. Đây là kiểu dữ liệu rất thường được sử dụng trong phát triển web. Đặc biệt là các APIs RESTful do tính tiện lợi trong cài đặt và dễ dàng trong parsing dữ liệu. Dưới đây là một ví dụ đơn giản, đọc lên một file .json và lấy ra một giá trị của dữ liệu.
Input: colors.json
Snippets:
import json with open("data/colors.json") as json_data: document = json.load(json_data) print "Getting blue value:", document["blue"]
Output:
## PARSING json Getting blue value: #00f
Github API
Ta có thể vọc nhiều hơn với JSON thông qua Github API. Giả sử bạn có các repos trên Github, bạn có thể sử dụng Github API để tải về thông tin của những repos này dưới định dạng JSON. Nhiệm vụ của bạn là rút ra một vài thông tin hữu ích sau đó xuất ra màn hình.
Snippet:
import json import requests from dateutil.parser import parse from collections import Counter endpoint = "https://api.github.com/users/ongxuanhong/repos" repos = json.loads(requests.get(endpoint).text) dates = [parse(repo["created_at"]) for repo in repos] month_counts = Counter(date.month for date in dates) weekday_counts = Counter(date.weekday() for date in dates) print "dates", [d.strftime("%d/%m/%y") for d in dates] print "month_counts", month_counts print "weekday_count", weekday_counts last_5_repositories = sorted(repos, key=lambda r: r["created_at"], reverse=True)[:5] print "last five repos", [repo["name"] for repo in last_5_repositories]
Output:
## GitHub API dates ['08/12/15', '25/08/15', '24/08/15', '07/07/16', '27/08/15', '16/10/16', '31/08/15', '23/08/16', '08/12/15', '21/05/16', '10/10/16', '06/10/15', '05/07/15', '21/03/16', '02/10/16', '07/12/15', '01/09/15', '03/09/15', '20/08/15', '22/11/15', '30/01/16', '05/03/16', '17/09/15', '17/09/15', '28/06/16', '20/04/16', '29/08/15'] month_counts Counter({8: 7, 9: 4, 10: 4, 12: 3, 3: 2, 7: 2, 1: 1, 4: 1, 5: 1, 6: 1, 11: 1}) weekday_count Counter({1: 7, 3: 6, 0: 5, 5: 4, 6: 4, 2: 1}) last five repos [u'data-science-works', u'java-snippets', u'kse-2016', u'hmm', u'aws-dsp-analysis']
Crawling Oreilly books
Các trang web là một trong những nguồn dữ liệu đa dạng và phong phú nhất. Bạn có thể viết các hàm crawling để thu thập dữ liệu. Trong ví dụ này, ta sẽ vào trang bán sách của Oreilly. Ta có thể điều hướng và duyệt danh sách trực tiếp qua URL nhờ vào tham số &page=[1,2,3,…].
Trong hàm scrap(), Crawler của chúng ta sẽ duyệt qua từng trang để lấy thông tin của các đầu sách (title, authors, isbn, date). Cuối cùng, ta sẽ thống kê số lượng sách cho từng năm và xuất ra biểu đồ cột để so sánh.
import requests, re import matplotlib.pyplot as plt from bs4 import BeautifulSoup from collections import Counter def is_video(td): """it's a video if it has exactly one pricelabel, and if the stripped text inside that pricelabel starts with 'Video'""" price_labels = td('span', 'pricelabel') return (len(price_labels) == 1 and price_labels[0].text.strip().startswith("Video")) def book_info(td): """given a BeautifulSoup Tag representing a book, extract the book's details and return a dict""" title = td.find("div", "thumbheader").a.text by_author = td.find('div', 'AuthorName').text authors = [x.strip() for x in re.sub("^By ", "", by_author).split(",")] isbn_link = td.find("div", "thumbheader").a.get("href") isbn = re.match("/product/(.*)\.do", isbn_link).groups()[0] date = td.find("span", "directorydate").text.strip() return { "title": title, "authors": authors, "isbn": isbn, "date": date } def scrape(num_pages=10): base_url = "http://shop.oreilly.com/category/browse-subjects/data.do?sortby=publicationDate&page=" books = [] for page_num in range(1, num_pages + 1): print "souping page", page_num url = base_url + str(page_num) soup = BeautifulSoup(requests.get(url).text, 'lxml') for td in soup('td', 'thumbtext'): if not is_video(td): books.append(book_info(td)) return books def get_year(book): """book["date"] looks like 'November 2016' so we need to split on the space and then take the second piece""" return int(book["date"].split()[1]) def plot_years(plt, books): # 2016 is the last complete year of data (when I ran this) year_counts = Counter(get_year(book) for book in books if get_year(book) & <= 2016) years = sorted(year_counts) book_counts = [year_counts[year] for year in years] plt.bar([x - 0.5 for x in years], book_counts) plt.xlabel("year") plt.ylabel("# of data books") plt.title("Data is Big!") plt.show() books = scrape() plot_years(plt, books)
Output:
## Oreilly books souping page 1 souping page 2 souping page 3 souping page 4 souping page 5 souping page 6 souping page 7 souping page 8 souping page 9 souping page 10
Twitter search API
Twitter cũng cung cấp cho ta API để tìm kiếm các status trên mạng xã hội này. Nhờ vào dữ liệu thu thập được, các nhà phân tích có thể dựa vào đây để đưa ra những khám phá hay những dự đoán thú vị như cuộc bầu cử tổng thống Mĩ ai đang là người được nhiều sự ủng hộ, hay dự báo thời tiết dựa vào trạng thái tâm lý của người dùng trong cộng đồng, … Ví dụ bên dưới chỉ đơn giản tìm kiếm các status có chứa từ khoá “data science” và in ra các trạng thái và tên người dùng tương ứng với kết quả tìm kiếm.
from twython import Twython CONSUMER_KEY = "JeuEwD5RJiBbxiw9jTMBYBEmU" CONSUMER_SECRET = "xRcmv8AMnSSMwq875HiP1SKFfGw51M97BvVH341yckPY3iilCu" ACCESS_TOKEN = "47319754-NL1AIh9PBomIVsJe5HXB9vjE5y1rjwZFYUQx0odzo" ACCESS_TOKEN_SECRET = "kcq7ER8UZSykDomPn9lYdh5DAafndvp73PzSfykTq0Kp7" def call_twitter_search_api(): twitter = Twython(CONSUMER_KEY, CONSUMER_SECRET) # search for tweets containing the phrase "data science" for status in twitter.search(q='"data science"')["statuses"]: user = status["user"]["screen_name"].encode('utf-8') text = status["text"].encode('utf-8') print user, ":", text print call_twitter_search_api() # generating hash import hashlib hash_object = hashlib.sha256(b'app_favorite_name') hex_dig = hash_object.hexdigest() print(hex_dig)
Output:
## Twitter search NikiEmbers : RT @BuyBookstore: A collection of Data Science Interview Questions S https://t.co/Nm8tplRFNm #amreading #mondaymotivation KatStilesAuthor : RT @BuyBookstore: A collection of Data Science Interview Questions S https://t.co/Nm8tplRFNm #amreading #mondaymotivation careersingrowth : A Career You Can’t Ignore – #Data #Science https://t.co/BKGQVRWO0q codearmster : RT @bicorner: Driving Value With #DataScience https://t.co/9SYEbrHwVu https://t.co/SG36fSrgjQ bicorner : Driving Value With #DataScience https://t.co/9SYEbrHwVu https://t.co/SG36fSrgjQ Joyce_Stack : Data Science track today will be held at 3:05 pm. We have some great talks on managing your data layer. Come along #APIStrat badc0da : "Upcoming Meetings in Analytics, Big Data, Data Mining, Data Science: November and Beyond" https://t.co/xy6l47AkP3 Joyce_Stack : RT @wiredferret: Tomorrow at 3 PM, I'm speaking on The Death of Data at @apistrat #apistrat as part of the Data Science track. lisachwinter : RT @ThoBoDo: A good start in Data Science is also to begin with approachable Analytics. Start doing is better than still Talking https://t.… megu19g3 : RT @IBMBluemix: Wrap your mind around the new data-science tools in Bluemix: Manipulating #NoSQL data with #Python. https://t.co/pWtdesJNFo… lc0d3r : That's data-driven approach! - Hacking my infant twins’ sleep with machine learning and data science https://t.co/blriwO3nm9 #DataScience accaminero : RT @analyticbridge: Answers to dozens of data science job interview questions https://t.co/O5OZT65V7I michaelyoungMBN : RT @KrissHampton: Latest production for @DataLabScotland promoting their data science bootcamp https://t.co/6CGHZrjqwb #videoproduction #Fi… AxiomtekUK : Data Science for Internet of Things (IoT) : Ten Differences From Traditional Data Science - https://t.co/9Tim5RKjeT thm10004353 : RT @IBMBluemix: Wrap your mind around the new data-science tools in Bluemix: Manipulating #NoSQL data with #Python. https://t.co/pWtdesJNFo…
Dear anh,
Có công cụ Kettle pentaho – công cụ này rất linh động trong việc thu thập dữ liệu qua các hình thức: Đồng bộ DB-DB, file, service, …
ThíchĐã thích bởi 1 người
Công cụ em chia sẻ khá hay, rất tiện cho người dùng (y)
ThíchĐã thích bởi 1 người
Công cụ này em đã sử dụng khá lâu, có vấn đề gì cần support các anh chị trao đổi chia sẻ nhé
ThíchĐã thích bởi 1 người
dá
ThíchThích