<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0">

<channel>

<title>LEFT JOIN: blog on analytics, visualisation &amp; data science, posts tagged: pandas</title>
<link>https://en.leftjoin.ru/tags/pandas/</link>
<description></description>
<generator>E2 (v3386; Aegea)</generator>

<item>
<title>Mean VS median: how to choose a target metric?</title>
<guid isPermaLink="false">71</guid>
<link>https://en.leftjoin.ru/all/mean-vs-median/</link>
<comments>https://en.leftjoin.ru/all/mean-vs-median/</comments>
<description>
&lt;p&gt;In today’s article, we would like to highlight a simple, but important topic – how to choose a simple metric to evaluate a particular dataset. Everyone has been familiar with the arithmetic mean for a long time, almost every student knows very well that you should sum up all the available values, divide by their number and get the average value. However, school knowledge does not include any alternative options, of which, in fact, there are many in statistics – almost for every occasion. In solving research and marketing problems, people often take mean as a target. Is this legitimate or is there a better option? Let’s figure it out.&lt;/p&gt;
&lt;p&gt;To begin with, it is worth remembering the definitions of the two metrics that we will talk about today.&lt;br /&gt;
Mean is the most popular statistic used to calculate a data center. What is the median? Median is a value that splits data, sorted in order of increasing values, into two equal parts. This means that the median shows the central value in the sample if the number of cases is odd and the arithmetic mean of the two values ​​if the number of cases in the sample is even.&lt;/p&gt;
&lt;h2&gt;Research tasks&lt;/h2&gt;
&lt;p&gt;So, the estimation of the sample mean is often important in many research questions. For instance, specialists studying demography often study changes in the number of regions in Russia in order to track the dynamics and reflect it in reports. Let’s try to calculate the average size of the Russian city, as well as the median, and then compare the results.&lt;br /&gt;
First, you need to find and load data by connecting the pandas library for this.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import pandas as pd
city = pd.read_csv('city.csv', sep = ';')&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, you need to calculate the mean and median of the sample.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;mean_pop = round (city.population_2020.mean (), 0)
median_pop = round (city.population_2020.median (), 0)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The values, of course, are different, since the distribution of observations in the sample is different from the normal one. In order to understand whether they are very different, let’s build a distribution graph and display the mean and median.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import matplotlib.pyplot as plt
import seaborn as sns

sns.set_palette('rainbow')
fig = plt.figure(figsize = (20, 15))
ax = fig.add_subplot(1, 1, 1)
g = sns.histplot(data = city, x= 'population_2020', alpha=0.6, bins = 100, ax=ax)

g.axvline(mean_pop, linewidth=2, color='r', alpha=0.9, linestyle='--', label = 'Mean = {:,.0f}'.format(mean_pop).replace(',', ' '))
g.axvline(median_pop, linewidth=2, color='darkgreen', alpha=0.9, linestyle='--', label = 'Median = {:,.0f}'.format(median_pop).replace(',', ' '))

plt.ticklabel_format(axis='x', style='plain')
plt.xlabel(&amp;quot;Population&amp;quot;, fontsize=20)
plt.ylabel(&amp;quot;Number of cities&amp;quot;, fontsize=20)
plt.title(&amp;quot;Distribution of population of russian cities&amp;quot;, fontsize=20)
plt.legend(fontsize=&amp;quot;xx-large&amp;quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/first.jpg" width="1440" height="1080" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Also, on this data it is worth building a boxplot for more accurate visualization with the main distribution quantiles, median, mean and outliers.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;fig = plt.figure(figsize = (10, 10))
sns.set_theme(style=&amp;quot;whitegrid&amp;quot;)
sns.set_palette(palette=&amp;quot;pastel&amp;quot;)

sns.boxplot(y = city['population_2020'], showfliers = False)

plt.scatter(0, 550100, marker='*', s=100, color = 'black', label = 'Outlier')
plt.scatter(0, 560200, marker='*', s=100, color = 'black')
plt.scatter(0, 570300, marker='*', s=100, color = 'black')
plt.scatter(0, mean_pop, marker='o', s=100, color = 'red', edgecolors = 'black', label = 'Mean')
plt.legend()

plt.ylabel(&amp;quot;Population&amp;quot;, fontsize=15)
plt.ticklabel_format(axis='y', style='plain')
plt.title(&amp;quot;Boxplot of population of russian cities&amp;quot;, fontsize=15)
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/second.jpg" width="720" height="720" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;It follows from the graphs that the median is significantly less than the average, and it is also clear that this is a consequence of the presence of outliers which are Moscow and St. Petersburg. Since the arithmetic mean is an extremely sensitive metric to outliers, it is not worth relying on conclusions about the mean if they are present in the sample. An increase or decrease in the population of Moscow can greatly change the average population in Russia, but this will not affect the real regional trend.&lt;br /&gt;
Using the arithmetic mean, we say that the number of a typical (average) city in the Russian Federation is 268 thousand people. However, this misleads us, since the mean value is significantly higher than the median solely due to the size of the population of Moscow and St. Petersburg. In fact, the number of a typical Russian city is significantly less (2 times less!) and is approximately 104 thousand citizens.&lt;/p&gt;
&lt;h2&gt;Marketing tasks&lt;/h2&gt;
&lt;p&gt;In a business tasks, the difference between the mean and the median is also important, as using the wrong metric can seriously affect the results of the advertising campaign or make it difficult to achieve the goal. Let’s take a look at a real example of the difficulties an entrepreneur can face in retail if he chooses the wrong target metric.&lt;br /&gt;
To begin with, as in the previous example, let’s load a dataset about supermarket purchases. Let’s select the dataset columns necessary for analysis and rename them to simplify the code in the future. Since this data is not as well prepared as the previous ones, it is necessary to group all purchased items by receipts. In this case, it is necessary to group by two variables: by the customer’s id and by the date of purchase (the date and time is determined by the moment of closing the bill, therefore, all purchases within one bill coincide by date variable). Then, let’s name the resulting column “total_bill”, that is, the check amount and calculate the average and median.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;df = pd.read_excel ('invoice_data.xlsx')
df.columns = ['user', 'total_price', 'date']
groupped_df = pd.DataFrame (df.groupby (['user', 'date']). total_price.sum ())
groupped_df.columns = ['total_bill']
mean_bill = groupped_df.total_bill.mean ()
median_bill = groupped_df.total_bill.median ()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, as in the previous example, you need to plot the distribution of customer checks and boxplot, and also display the median and mean on each of them.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;sns.set_palette('rainbow')
fig = plt.figure(figsize = (20, 15))
ax = fig.add_subplot(1, 1, 1)
sns.histplot(groupped_df, x = 'total_bill', binwidth=200, alpha=0.6, ax=ax)
plt.xlabel(&amp;quot;Purchases&amp;quot;, fontsize=20)
plt.ylabel(&amp;quot;Total bill&amp;quot;, fontsize=20)
plt.title(&amp;quot;Distribution of total bills&amp;quot;, fontsize=20)
plt.axvline(mean_bill, linewidth=2, color='r', alpha=1, linestyle='--', label = 'Mean = {:.0f}'.format(mean_bill))
plt.axvline(median_bill, linewidth=2, color='darkgreen', alpha=1, linestyle='--', label = 'Median = {:.0f}'.format(median_bill))
plt.legend(fontsize=&amp;quot;xx-large&amp;quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/third.jpg" width="1440" height="1080" alt="" /&gt;
&lt;/div&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;fig = plt.figure(figsize = (10, 10))
sns.set_theme(style=&amp;quot;whitegrid&amp;quot;)
sns.set_palette(palette=&amp;quot;pastel&amp;quot;)

sns.boxplot(y = groupped_df['total_bill'], showfliers = False)

plt.scatter(0, 1800, marker='*', s=100, color = 'black', label = 'Outlier')
plt.scatter(0, 1850, marker='*', s=100, color = 'black')
plt.scatter(0, 1900, marker='*', s=100, color = 'black')
plt.scatter(0, mean_bill, marker='o', s=100, color = 'red', edgecolors = 'black', label = 'Mean')
plt.legend()

plt.ticklabel_format(axis='y', style='plain')
plt.ylabel(&amp;quot;Total bill&amp;quot;, fontsize=15)
plt.title(&amp;quot;Boxplot of total bills&amp;quot;, fontsize=15)
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/forth.jpg" width="720" height="720" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;The graphs show that the distribution is different from normal, which means that the median and mean are not equal. The median value is smaller than the average by about 220 rubles.&lt;br /&gt;
Now, imagine that marketers have a task to increase the average buyer’s bill. A marketer may decide that since the average check is 601 rubles, the following promotion can be offered: “All buyers who make a purchase over 600 rubles, will get 20% discount on any good for 100 rubles.” In general, it is a reasonable offer, however, in reality, the average check is lower – 378 rubles. Thus, the majority of buyers will not be interested in the offer, since their purchase usually does not reach the proposed threshold. This means, that they will not take advantage of the offer and will not receive a discount, and the company will not be able to achieve its goal and increase the profit. The point is that the initial assumptions were wrong.&lt;/p&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;As you already understood, the mean often shows a more pleasant result, both for business and for research tasks, because it is always nicer to imagine the situation with the average check or the demographic situation in the country better than it really is. However, one must always remember about the shortcomings of mean in order to be able to correctly choose the appropriate analogue for assessing a particular situation.&lt;/p&gt;
</description>
<pubDate>Wed, 27 Oct 2021 14:20:56 +0300</pubDate>
</item>

<item>
<title>Pandas Profiling in action:  reviewing a new EDA library on Superstore Sales dataset</title>
<guid isPermaLink="false">39</guid>
<link>https://en.leftjoin.ru/all/pandas-profiling-in-action/</link>
<comments>https://en.leftjoin.ru/all/pandas-profiling-in-action/</comments>
<description>
&lt;p&gt;Before moving directly to data analysis we need to understand what type of data we are going to work with. In today’s material, we will take a closer look at the SuperStore Sales dataset, specifically at the &lt;i&gt;Orders&lt;/i&gt; column. It includes customer shopping data of a Canadian online supermarket, such as order, product and customer ids,  type of shipping, prices, product categories, names and etc. You can find more information about this dataset on &lt;a href="https://github.com/PacktPublishing/Tableau-10-Best-Practices/blob/master/Chapter%205/Sample%20-%20Superstore%20Sales%20(Excel).xls"&gt;GitHub&lt;/a&gt;. After creating a pandas DataFrame we can simply  use the &lt;span class="inline-code"&gt;describe()&lt;/span&gt; method to get a sense of our data.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import pandas as pd

df = pd.read_csv('superstore_sales_orders.csv', decimal=',')
df.describe(include='all')&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And oftentimes it leads to such a mess:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/1-15.png" width="984" height="427" alt="" /&gt;
&lt;/div&gt;
&lt;p class="note"&gt;The source code of this library is available on &lt;a href="https://github.com/pandas-profiling/pandas-profiling"&gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If we spend some time trying to get a grasp of this descriptive table,  we can find out that customers are more likely to choose “Regular air” as a shipping type or that the majority of orders were made from Ontario.  Nevertheless, there is a better tool to describe the dataset in more detail  – the pandas-profiling library.  Just pass a DataFrame to it and we will get a generated HTML page with a detailed description of our dataset:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import pandas_profiling
profile = pandas_profiling.ProfileReport(df)
profile.to_file(&amp;quot;output.html&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/2-15.png" width="973" height="621" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;As you see, it returned a page with 6 sections, namely: overview, variables, interactions and correlations, number of missing values, and dataset samples.&lt;/p&gt;
&lt;p class="note"&gt;View a full version of the &lt;a href="http://leftjoin.ru/files/superstore.html"&gt;Pandas Profiling Report&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Data overview&lt;/h2&gt;
&lt;p&gt;Let’s move to the first subsection called “Overview”.  Pandas Profiling provided the following stats: number of variables, number of observations, missing cells, duplicates, and file size. The  &lt;span class="inline-code"&gt;Variable types&lt;/span&gt;  column shows that our DataFrame consists of 12 categorical and 9 numerical variables.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/3-14.png" width="737" height="356" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;The  “Reproduction”  subsection stores technical information,  showing how long it took to analyze the dataset,  currently installed version , configuration info and etc.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/4-12.png" width="725" height="293" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;The  “Warnings”  subsection informs about possible issues in the dataset structure. Now,  it warns us that the “Order Date” column has too many distinct values.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/5_5.png" width="712" height="485" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Variables&lt;/h2&gt;
&lt;p&gt;Moving further, this subsection contains a detailed description of each variable, displaying the number of duplicates and missing values stored, memory size, maximum and minimal values. Right next to the stats you can see the distribution of column values.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/6_6.png" width="722" height="282" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Clicking on  &lt;span class="inline-code"&gt;Toggle details&lt;/span&gt;  you will see more expanded information:  quartiles, median and other useful descriptive statistical indicators. The remaining tabs contain a histogram displayed on the main screen, top 10 frequent values and extremes.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/7_7.png" width="737" height="404" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Interactions&lt;/h2&gt;
&lt;p&gt;This section displays how variables are interconnected on a hexbin plot: The graph looks not very obvious and clear, since the legend is lacking.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/8_8.png" width="716" height="548" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Correlations&lt;/h2&gt;
&lt;p&gt;The section represents correlations between variables calculated in a variety of ways. For example, the first tab shows Pearson’s r-value. It is noticeable that &lt;span class="inline-code"&gt;Profit &lt;/span&gt; is positively correlated with  &lt;span class="inline-code"&gt;Sales&lt;/span&gt;.  You can get a detailed explanation to each coefficient by clicking on the &lt;span class="inline-code"&gt;Toggle correlation descriptions&lt;/span&gt; button.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/9_9.png" width="739" height="554" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Missing values&lt;/h2&gt;
&lt;p&gt;This section includes a bar chart, matrix, and dendrogram with the number of fields in each variable. For instance,  the  &lt;span class="inline-code"&gt;Product Base Margin&lt;/span&gt;  column is missing three values.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/10_10.png" width="739" height="411" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Samples&lt;/h2&gt;
&lt;p&gt;And the final section show the first and last 10 rows as chunks of a dataset, pretty similar to the  &lt;span class="inline-code"&gt;head()&lt;/span&gt;  method in Pandas.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/11_11.png" width="661" height="469" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Key Takeaways&lt;/h2&gt;
&lt;p&gt;The library is definitely more focused on statistics than Pandas, one can get useful descriptive stats for each variable and see their correlation.  It provides a comprehensive report on a dataset in a user-friendly way,  allowing to undertake an initial investigation and get a sense of data.&lt;br /&gt;
Still, the library has its shortfalls. If your dataset is fairly large the report generation time may be extended up to several hours. It’s a great tool for automating EDA tasks,  however, it can’t do all the work for you and some details may be overlooked. If you are just getting started with data analysis, we would highly recommend to start it with pandas. It will solidify your knowledge and boost confidence in working with data.&lt;/p&gt;
</description>
<pubDate>Fri, 18 Sep 2020 15:37:40 +0300</pubDate>
</item>

<item>
<title>Collecting data from hypermarket receipts on Python</title>
<guid isPermaLink="false">6</guid>
<link>https://en.leftjoin.ru/all/collecting-receipts-with-python-p1/</link>
<comments>https://en.leftjoin.ru/all/collecting-receipts-with-python-p1/</comments>
<description>
&lt;p&gt;Recently, once again buying products in a hypermarket, I recalled that, according to the Russian Federal Act FZ-54, any trade operator, that issues a receipt, is obliged to send the data thereof to the Tax Service.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/lenta-receipt@2x.jpg" width="787" height="762" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Receipt from “Lenta” hypermarket. The QR-code of our interest is circled.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So, what does it mean for us, data analysts? It means that we can know ourselves and our needs better, and also acquire interesting data on own purchases.&lt;/p&gt;
&lt;p&gt;Let’s try to assemble a small prototype of an app that will allow to make a dynamic of our purchases within the framework of blog posts’ series. So, we’ll start from the fact, that each receipt has a QR-code, and if you identify it, you’ll receive the following line:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;t=20190320T2303&amp;s=5803.00&amp;fn=9251440300007971&amp;i=141637&amp;fp=4087570038&amp;n=1&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This line comprises:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;t&lt;/i&gt; – timestamp, the time when you made a purchase&lt;br /&gt;
&lt;i&gt;s&lt;/i&gt; – sum of the receipt&lt;br /&gt;
&lt;i&gt;fn&lt;/i&gt; – code number of fss, will be needed further in a request to API&lt;br /&gt;
&lt;i&gt;i&lt;/i&gt; – receipt number, will be needed further in a request to API&lt;br /&gt;
&lt;i&gt;fp&lt;/i&gt; – fiscalsign parameter, will be needed further in a request to API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Within the solution of the first step, we will parse the receipt data and collect it in &lt;i&gt;pandas&lt;/i&gt; dataframe, using Python modules.&lt;/p&gt;
&lt;p&gt;We will use &lt;a href="https://habr.com/ru/post/358966/"&gt;API&lt;/a&gt;, that provides data on the receipt from the Tax Service website.&lt;/p&gt;
&lt;p&gt;Initially, we will receive authentication data:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import requests
your_phone = '+7XXXYYYZZZZ' #you need to state your phone number, SMS with password will arrive thereon
r = requests.post('https://proverkacheka.nalog.ru:9999/v1/mobile/users/signup', json = {&amp;quot;email&amp;quot;:&amp;quot;email@email.com&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;USERNAME&amp;quot;,&amp;quot;phone&amp;quot;:your_phone})&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As a result of performing POST request we receive a password in SMS to the indicated phone number. Further on, we will be using it in a variable &lt;i&gt;&lt;b&gt;pwd&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Now we’ll parse our line with values from QR-code:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import re
qr_string='t=20190320T2303&amp;amp;s=5803.00&amp;amp;fn=9251440300007971&amp;amp;i=141637&amp;amp;fp=4087570038&amp;amp;n=1'
t=re.findall(r't=(\w+)', qr_string)[0]
s=re.findall(r's=(\w+)', qr_string)[0]
fn=re.findall(r'fn=(\w+)', qr_string)[0]
i=re.findall(r'i=(\w+)', qr_string)[0]
fp=re.findall(r'fp=(\w+)', qr_string)[0]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We’ll use the variables obtained in order to extract the data.&lt;br /&gt;
One &lt;a href="https://habr.com/ru/post/358966/"&gt;Habr post&lt;/a&gt; pretty thoroughly examines status of errors at formation of API request, therefore I won’t repeat this information.&lt;/p&gt;
&lt;p&gt;In the beginning, we need to verify the presence of data on this receipt, so we form a GET request.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;headers = {'Device-Id':'', 'Device-OS':''}
payload = {'fiscalSign': fp, 'date': t,'sum':s}
check_request=requests.get('https://proverkacheka.nalog.ru:9999/v1/ofds/*/inns/*/fss/'+fn+'/operations/1/tickets/'+i,params=payload, headers=headers,auth=(your_phone, pwd))
print(check_request.status_code)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the request one needs to indicate headers, at least empty ones. In my case, GET request returns error 406, thus I get that such receipt is found (why GET request returns 406 remains a mystery to me, so I will be glad to receive some clues in comments). If not indicating sum or date, GET request returns error 400 – bad request.&lt;/p&gt;
&lt;p&gt;Let’s move on to the most interesting part, receiving data of the receipt:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;request_info=requests.get('https://proverkacheka.nalog.ru:9999/v1/inns/*/kkts/*/fss/'+fn+'/tickets/'+i+'?fiscalSign='+fp+'&amp;amp;sendToEmail=no',headers=headers,auth=(your_phone, pwd))
print(request_info.status_code)
products=request_info.json()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We should receive code 200 (successful execution of the request), and in the variable &lt;i&gt;products&lt;/i&gt; – everything, that applies to our receipt.&lt;/p&gt;
&lt;p&gt;In order to further work with this data, let’s use &lt;i&gt;pandas&lt;/i&gt; and transform everything in dataframe.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import pandas as pd
from datetime import datetime
my_products=pd.DataFrame(products['document']['receipt']['items'])
my_products['price']=my_products['price']/100
my_products['sum']=my_products['sum']/100
datetime_check = datetime.strptime(t, '%Y%m%dT%H%M') #((https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior formate the date))
my_products['date']=datetime_check
my_products.set_index('date',inplace=True)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we have working pandas.dataframe with receipts, visually it looks as follows:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/2019-03-22_17-14-33@2x.png" width="679" height="374" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;“Header” of receipt data&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can construct a bar chart of purchases or observe everything as a box plot:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import matplotlib.pyplot as plt
%matplotlib inline
my_products['sum'].plot(kind='hist', bins=20)
plt.show()
my_products['sum'].plot(kind='box')
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/hist_cheques.png" width="386" height="252" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;boxplot_cheques.png&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In conclusion, we will simply get descriptive statistics as text, using a command &lt;i&gt;.describe()&lt;/i&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;my_products.describe()&lt;/code&gt;&lt;/pre&gt;&lt;div class="e2-text-picture"&gt;
&lt;img src="https://en.leftjoin.ru/pictures/2019-03-22_17-27-06@2x.png" width="362" height="268" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;It’s convenient to write down data as .csv file, so that the next time you can amend the statistics:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;with open('hyper_receipts.csv', 'a') as f:
             my_products.to_csv(f, header=True)&lt;/code&gt;&lt;/pre&gt;</description>
<pubDate>Fri, 22 Mar 2019 17:41:37 +0300</pubDate>
</item>


</channel>
</rss>