def ConvertOfferHistory(csv, as_datetime=True): """ Converts an offer history to human readable values Parameters ---------- csv : list Offer list csv obtained from ['offerCSV'] Returns ------- times : numpy.ndarray List of time values for an offer history. prices : numpy.ndarray Price (including shipping) of an offer for each time at an index of times. """ # convert these values to numpy arrays times = csv[::3] values = np.array(csv[1::3]) values += np.array(csv[2::3]) # add in shipping # convert to dollars and datetimes to_datetime = True times = keepaTime.KeepaMinutesToTime(times, to_datetime) prices = values / 100.0 return times, prices
def ParseCSV(csv, to_datetime): """ Parses csv list from keepa into a python dictionary csv is organized as the following index item 0 Amazon Price 1 Marketplace New 2 Marketplace Used 3 Sales Rank 4 Listing Price 5 Collectable Price 11 New Offers 12 Used Offers 14 Collectable Offers 16 Rating """ # index in csv, key name, isfloat (is price) indices = [[0, 'AmazonPrice', True], [1, 'MarketplaceNew', True], [2, 'MarketplaceUsed', True], [3, 'SalesRank', False], [4, 'ListingPrice', True], [5, 'CollectablePrice', True], [11, 'NewOffers', False], [12, 'UsedOffers', False], [14, 'CollectableOffers', False], [16, 'Rating', False]] product_data = {} for index in indices: # Check if it exists ind = index[0] if csv[ind]: key = index[1] # Data goes [time0, value0, time1, value1, ...] product_data[key + '_time'] = keepaTime.KeepaMinutesToTime( csv[ind][::2], to_datetime) # Convert to float price if applicable if index[2]: product_data[key] = np.array(csv[ind][1::2], np.float) / 100.0 else: if index[1] == 'Rating': product_data[key] = np.asarray(csv[ind][1::2], np.float) / 10.0 else: product_data[key] = np.asarray(csv[ind][1::2]) return product_data
def ParseCSV(csv, to_datetime): """ Parses csv list from keepa into a python dictionary Parameters ---------- csv : list csv list from keepa Returns ------- product_data : dict Dictionary containing the following fields with timestamps: AMAZON Amazon price history NEW Marketplace/3rd party New price history - Amazon is considered to be part of the marketplace as well, so if Amazon has the overall lowest new (!) price, the marketplace new price in the corresponding time interval will be identical to the Amazon price (except if there is only one marketplace offer). Shipping and Handling costs not included! USED Marketplace/3rd party Used price history SALES Sales Rank history. Not every product has a Sales Rank. LISTPRICE List Price history 5 COLLECTIBLE Collectible Price history 6 REFURBISHED Refurbished Price history 7 NEW_FBM_SHIPPING 3rd party (not including Amazon) New price history including shipping costs, only fulfilled by merchant (FBM). 8 LIGHTNING_DEAL 3rd party (not including Amazon) New price history including shipping costs, only fulfilled by merchant (FBM). 9 WAREHOUSE Amazon Warehouse Deals price history. Mostly of used condition, rarely new. 10 NEW_FBA Price history of the lowest 3rd party (not including Amazon/Warehouse) New offer that is fulfilled by Amazon 11 COUNT_NEW New offer count history 12 COUNT_USED Used offer count history 13 COUNT_REFURBISHED Refurbished offer count history 14 COUNT_COLLECTIBLE Collectible offer count history 16 RATING The product's rating history. A rating is an integer from 0 to 50 (e.g. 45 = 4.5 stars) 17 COUNT_REVIEWS The product's review count history. 18 BUY_BOX_SHIPPING(18, true, false, true, true), The price history of the buy box. If no offer qualified for the buy box the price has the value -1. Including shipping costs. 19 USED_NEW_SHIPPING(19, true, true, true, true), "Used - Like New" price history including shipping costs. 20 USED_VERY_GOOD_SHIPPING(20, true, true, true, true), "Used - Very Good" price history including shipping costs. 21 USED_GOOD_SHIPPING(21, true, true, true, true), "Used - Good" price history including shipping costs. 22 USED_ACCEPTABLE_SHIPPING(22, true, true, true, true), "Used - Acceptable" price history including shipping costs. 23 COLLECTIBLE_NEW_SHIPPING(23, true, true, true, true), "Collectible - Like New" price history including shipping costs. 24 COLLECTIBLE_VERY_GOOD_SHIPPING(24, true, true, true, true), "Collectible - Very Good" price history including shipping costs. 25 COLLECTIBLE_GOOD_SHIPPING(25, true, true, true, true), "Collectible - Good" price history including shipping costs. 26 COLLECTIBLE_ACCEPTABLE_SHIPPING(26, true, true, true, true), "Collectible - Acceptable" price history including shipping costs. 27 REFURBISHED_SHIPPING Refurbished price history including shipping costs. 30 TRADE_IN The trade in price history. Amazon trade-in is not available for every locale. """ # [index in csv, key name, isfloat (is price)] indices = [[ 0, 'AMAZON', True], [ 1, 'NEW', True], [ 2, 'USED', True], [ 3, 'SALES', False], [ 4, 'LISTPRICE', True], [ 5, 'COLLECTIBLE', True], [ 6, 'REFURBISHED', True], [ 7, 'NEW_FBM_SHIPPING', True], [ 8, 'LIGHTNING_DEAL', True], [ 9, 'WAREHOUSE', True], [10, 'NEW_FBA', True], [11, 'COUNT_NEW', False], [12, 'COUNT_USED', False], [13, 'COUNT_REFURBISHED', False], [14, 'CollectableOffers', False], [16, 'RATING', False], [17, 'COUNT_REVIEWS', False], [18, 'BUY_BOX_SHIPPING', True], [19, 'USED_NEW_SHIPPING', True], [20, 'USED_VERY_GOOD_SHIPPING', True], [21, 'USED_GOOD_SHIPPING', True], [22, 'USED_ACCEPTABLE_SHIPPING', True], [23, 'COLLECTIBLE_NEW_SHIPPING', True], [24, 'COLLECTIBLE_VERY_GOOD_SHIPPING', True], [25, 'COLLECTIBLE_GOOD_SHIPPING', True], [26, 'COLLECTIBLE_ACCEPTABLE_SHIPPING', True], [27, 'REFURBISHED_SHIPPING', True], [30, 'TRADE_IN', True]] product_data = {} for index in indices: # Check if it exists ind = index[0] if csv[ind]: key = index[1] # Data goes [time0, value0, time1, value1, ...] product_data[key + '_time'] = keepaTime.KeepaMinutesToTime(csv[ind][::2], to_datetime) # Convert to float price if applicable if index[2]: product_data[key] = np.array(csv[ind][1::2], np.float)/100.0 else: if index[1] == 'Rating': product_data[key] = np.asarray( csv[ind][1::2], np.float)/10.0 else: product_data[key] = np.asarray(csv[ind][1::2]) return product_data
def PlotProduct(product, keys=['AMAZON', 'USED', 'COUNT_USED', 'SALES']): """ Plots a product using matplotlib Parameters ---------- product : list Single product from keepaAPI.ProductQuery keys : list, optional Keys to plot. Defaults to ['AMAZON', 'USED', 'COUNT_USED', 'SALES'] """ if not plt_loaded: raise Exception('Plotting not available. Check matplotlib install') # Use all keys if not specified if not keys: keys = product['data'].keys() # Create three figures, one for price data, offers, and sales rank pricefig, priceax = plt.subplots() pricefig.canvas.set_window_title('Product Price Plot') plt.title(product['title']) pricelegend = [] offerfig, offerax = plt.subplots() offerfig.canvas.set_window_title('Product Offer Plot') plt.title(product['title']) offerlegend = [] salesfig, salesax = plt.subplots() salesfig.canvas.set_window_title('Product Sales Rank Plot') plt.title(product['title']) saleslegend = [] # Add in last update time lstupdate = keepaTime.KeepaMinutesToTime(product['lastUpdate']) # Attempt to plot each key for key in keys: # Continue if key does not exist if key not in product['data'].keys(): continue elif 'SALES' in key and 'time' not in key: x = np.append(product['data'][key + '_time'], lstupdate) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) salesax.step(x, y, where='pre') saleslegend.append(key) elif 'COUNT_NEW' in key and 'time' not in key: x = np.append(product['data'][key + '_time'], lstupdate) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) offerax.step(x, y, where='pre') offerlegend.append(key) elif 'COUNT_USED' in key and 'time' not in key: x = np.append(product['data'][key + '_time'], lstupdate) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) offerax.step(x, y, where='pre') offerlegend.append(key) elif 'time' not in key: x = np.append(product['data'][key + '_time'], lstupdate) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) priceax.step(x, y, where='pre') pricelegend.append(key) # Add in legends or close figure if pricelegend: priceax.legend(pricelegend) else: plt.close(pricefig) if offerlegend: offerax.legend(offerlegend) else: plt.close(offerfig) if not saleslegend: plt.close(salesfig) plt.show(block=True) plt.draw()
def ParseCSV(csv, to_datetime): """Parses csv list from keepa into a python dictionary Parameters ---------- csv : list csv list from keepa Returns ------- product_data : dict Dictionary containing the following fields with timestamps: AMAZON: Amazon price history NEW: Marketplace/3rd party New price history - Amazon is considered to be part of the marketplace as well, so if Amazon has the overall lowest new (!) price, the marketplace new price in the corresponding time interval will be identical to the Amazon price (except if there is only one marketplace offer). Shipping and Handling costs not included! USED: Marketplace/3rd party Used price history SALES: Sales Rank history. Not every product has a Sales Rank. LISTPRICE: List Price history 5 COLLECTIBLE: Collectible Price history 6 REFURBISHED: Refurbished Price history 7 NEW_FBM_SHIPPING: 3rd party (not including Amazon) New price history including shipping costs, only fulfilled by merchant (FBM). 8 LIGHTNING_DEAL: 3rd party (not including Amazon) New price history including shipping costs, only fulfilled by merchant (FBM). 9 WAREHOUSE: Amazon Warehouse Deals price history. Mostly of used condition, rarely new. 10 NEW_FBA: Price history of the lowest 3rd party (not including Amazon/Warehouse) New offer that is fulfilled by Amazon 11 COUNT_NEW: New offer count history 12 COUNT_USED: Used offer count history 13 COUNT_REFURBISHED: Refurbished offer count history 14 COUNT_COLLECTIBLE: Collectible offer count history 16 RATING: The product's rating history. A rating is an integer from 0 to 50 (e.g. 45 = 4.5 stars) 17 COUNT_REVIEWS: The product's review count history. 18 BUY_BOX_SHIPPING: The price history of the buy box. If no offer qualified for the buy box the price has the value -1. Including shipping costs. 19 USED_NEW_SHIPPING: "Used - Like New" price history including shipping costs. 20 USED_VERY_GOOD_SHIPPING: "Used - Very Good" price history including shipping costs. 21 USED_GOOD_SHIPPING: "Used - Good" price history including shipping costs. 22 USED_ACCEPTABLE_SHIPPING: "Used - Acceptable" price history including shipping costs. 23 COLLECTIBLE_NEW_SHIPPING: "Collectible - Like New" price history including shipping costs. 24 COLLECTIBLE_VERY_GOOD_SHIPPING: "Collectible - Very Good" price history including shipping costs. 25 COLLECTIBLE_GOOD_SHIPPING: "Collectible - Good" price history including shipping costs. 26 COLLECTIBLE_ACCEPTABLE_SHIPPING: "Collectible - Acceptable" price history including shipping costs. 27 REFURBISHED_SHIPPING: Refurbished price history including shipping costs. 30 TRADE_IN: The trade in price history. Amazon trade-in is not available for every locale. """ # [index in csv, key name, isfloat (is price)] indices = [[0, 'AMAZON', True], [1, 'NEW', True], [2, 'USED', True], [3, 'SALES', False], [4, 'LISTPRICE', True], [5, 'COLLECTIBLE', True], [6, 'REFURBISHED', True], [7, 'NEW_FBM_SHIPPING', True], [8, 'LIGHTNING_DEAL', True], [9, 'WAREHOUSE', True], [10, 'NEW_FBA', True], [11, 'COUNT_NEW', False], [12, 'COUNT_USED', False], [13, 'COUNT_REFURBISHED', False], [14, 'CollectableOffers', False], [16, 'RATING', True], [17, 'COUNT_REVIEWS', False], [18, 'BUY_BOX_SHIPPING', True], [19, 'USED_NEW_SHIPPING', True], [20, 'USED_VERY_GOOD_SHIPPING', True], [21, 'USED_GOOD_SHIPPING', True], [22, 'USED_ACCEPTABLE_SHIPPING', True], [23, 'COLLECTIBLE_NEW_SHIPPING', True], [24, 'COLLECTIBLE_VERY_GOOD_SHIPPING', True], [25, 'COLLECTIBLE_GOOD_SHIPPING', True], [26, 'COLLECTIBLE_ACCEPTABLE_SHIPPING', True], [27, 'REFURBISHED_SHIPPING', True], [30, 'TRADE_IN', True]] product_data = {} for ind, key, isfloat in indices: if csv[ind]: # Check if entry it exists if 'SHIPPING' in key: # shipping price is included # Data goes [time0, value0, shipping0, time1, value1, # shipping1, ...] times = csv[ind][::3] values = np.array(csv[ind][1::3]) values += np.array(csv[ind][2::3]) else: # Data goes [time0, value0, time1, value1, ...] times = csv[ind][::2] values = np.array(csv[ind][1::2]) if isfloat: # Convert to float price if applicable nanmask = values < 0 values = values.astype(np.float)/100 values[nanmask] = np.nan if key == 'RATING': values /= 10 timeval = keepaTime.KeepaMinutesToTime(times, to_datetime) product_data['%s_time' % key] = timeval product_data[key] = values return product_data
def PlotProduct(product, keys=[], rng=None): """ Plots a product using matplotlib """ if not plt_loaded: raise Exception('Plotting not available. Check matplotlib install') # Use all keys if not specified if not keys: keys = product['data'].keys() # Create three figures, one for price data, offers, and sales rank pricefig, priceax = plt.subplots() pricefig.canvas.set_window_title('Product Price Plot') plt.title(product['title']) pricelegend = [] offerfig, offerax = plt.subplots() offerfig.canvas.set_window_title('Product Offer Plot') plt.title(product['title']) offerlegend = [] salesfig, salesax = plt.subplots() salesfig.canvas.set_window_title('Product Sales Rank Plot') plt.title(product['title']) saleslegend = [] # Add in last update time lstupdate = keepaTime.KeepaMinutesToTime(product['lastUpdate']) # Attempt to plot each key for key in keys: # Continue if key does not exist if key not in product['data'].keys(): continue elif 'SalesRank' in key and not 'time' in key: x = np.append(product['data'][key + '_time'], lstupdate) # x = ConvertToDateTime(x) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) salesax.step(x, y, where='pre') saleslegend.append(key) elif 'Offers' in key and not 'time' in key: x = np.append(product['data'][key + '_time'], lstupdate) # x = ConvertToDateTime(x) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) offerax.step(x, y, where='pre') offerlegend.append(key) elif not 'time' in key: x = np.append(product['data'][key + '_time'], lstupdate) # x = ConvertToDateTime(x) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) priceax.step(x, y, where='pre') pricelegend.append(key) # Add in legends or close figure if pricelegend: priceax.legend(pricelegend) else: plt.close(pricefig) if offerlegend: offerax.legend(offerlegend) else: plt.close(offerfig) if not saleslegend: plt.close(salesfig) plt.show(block=True) plt.draw()
def PlotProduct(product, keys=['AMAZON', 'USED', 'COUNT_USED', 'SALES'], price_limit=1000): """ Plots a product using matplotlib Parameters ---------- product : list Single product from keepaAPI.ProductQuery keys : list, optional Keys to plot. Defaults to ['AMAZON', 'USED', 'COUNT_USED', 'SALES'] price_limit : float, optional Prices over this value will not be plotted. Used to ignore extreme prices. """ if not plt_loaded: raise Exception('Plotting not available. Install matplotlib with:\n' + 'pip install matplotlib') if 'data' not in product: product['data'] = ParseCSV[product['csv']] # Use all keys if not specified if not keys: keys = product['data'].keys() # Create three figures, one for price data, offers, and sales rank pricefig, priceax = plt.subplots(figsize=(10, 5)) pricefig.canvas.set_window_title('Product Price Plot') plt.title(product['title']) plt.xlabel('Date') plt.ylabel('Price') pricelegend = [] offerfig, offerax = plt.subplots(figsize=(10, 5)) offerfig.canvas.set_window_title('Product Offer Plot') plt.title(product['title']) plt.xlabel('Date') plt.ylabel('Listings') offerlegend = [] salesfig, salesax = plt.subplots(figsize=(10, 5)) salesfig.canvas.set_window_title('Product Sales Rank Plot') plt.title(product['title']) plt.xlabel('Date') plt.ylabel('Sales Rank') saleslegend = [] # Add in last update time lstupdate = keepaTime.KeepaMinutesToTime(product['lastUpdate']) # Attempt to plot each key for key in keys: # Continue if key does not exist if key not in product['data']: print('%s not in product' % key) continue elif 'SALES' in key and 'time' not in key: if product['data'][key].size == 1: print('%s not in product' % key) continue x = np.append(product['data'][key + '_time'], lstupdate) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) salesax.step(x, y, where='pre') saleslegend.append(key) elif 'COUNT_' in key and 'time' not in key: x = np.append(product['data'][key + '_time'], lstupdate) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y) offerax.step(x, y, where='pre') offerlegend.append(key) elif 'time' not in key: x = np.append(product['data'][key + '_time'], lstupdate) y = np.append(product['data'][key], product['data'][key][-1]).astype(np.float) ReplaceInvalid(y, max_value=price_limit) priceax.step(x, y, where='pre') pricelegend.append(key) # Add in legends or close figure if pricelegend: priceax.legend(pricelegend) else: plt.close(pricefig) if offerlegend: offerax.legend(offerlegend) else: plt.close(offerfig) if not saleslegend: plt.close(salesfig) plt.show(block=True) plt.draw()