{"id":504467,"date":"2024-09-16T11:48:55","date_gmt":"2024-09-16T10:48:55","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=504467"},"modified":"2025-09-16T16:11:41","modified_gmt":"2025-09-16T15:11:41","slug":"7-ways-to-use-jupyter-notebooks-inside-pycharm","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/pycharm\/2024\/09\/7-ways-to-use-jupyter-notebooks-inside-pycharm\/","title":{"rendered":"7 Ways To Use Jupyter Notebooks inside PyCharm"},"content":{"rendered":"\n<p>Jupyter notebooks allow you to tell stories by creating and sharing data, equations, and visualizations sequentially, with a supporting narrative as you go through the notebook.<\/p>\n\n\n\n<p>Jupyter notebooks in <a href=\"https:\/\/www.jetbrains.com\/pycharm\/data-science\/\" target=\"_blank\" rel=\"noopener\">PyCharm Professional<\/a> provide functionality above and beyond that of browser-based Jupyter notebooks, such as code completion, dynamic plots, and quick statistics, to help you explore and work with your data quickly and effectively.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Let\u2019s take a look at 7 ways you can use Jupyter notebooks in PyCharm to achieve your goals. They are:<\/p>\n\n\n\n<ul>\n<li>Creating or connecting to an existing notebook<\/li>\n\n\n\n<li>Importing your data<\/li>\n\n\n\n<li>Getting acquainted with your data<\/li>\n\n\n\n<li>Using JetBrains AI Assistant&nbsp;<\/li>\n\n\n\n<li>Exploring your code with PyCharm<\/li>\n\n\n\n<li>Getting insights from your code<\/li>\n\n\n\n<li>Sharing your insights and charts<\/li>\n<\/ul>\n\n\n\n<p>The Jupyter notebook that we used in this demo is available on <a href=\"https:\/\/github.com\/t-redactyl\/pycon-us-demos\/blob\/main\/demos\/airlines-analysis\/notebooks\/airport-exploration.ipynb\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Creating or connecting to an existing notebook<\/h2>\n\n\n\n<p>You can create and work on your Jupyter notebooks locally or connect to one remotely with PyCharm. Let\u2019s take a look at both options so you can decide for yourself.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a new Jupyter notebook<\/h3>\n\n\n\n<p>To work with a Jupyter notebook locally, you need to go to the <em>Project<\/em> tool window inside PyCharm, navigate to the location where you want to add the notebook, and invoke a new file. You can do this by using either&nbsp;your keyboard shortcuts <em>\u2318N<\/em> (macOS) \/ <em>Alt+Ins<\/em> (Windows\/Linux) or by right-clicking and selecting <em>New | Jupyter Notebook<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1018\" height=\"1600\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-2.png\" alt=\"\" class=\"wp-image-536546\"\/><\/figure>\n\n\n\n<p>Give your new notebook a name, and PyCharm will open it ready for you to start work. You can also drag local Jupyter notebooks into PyCharm, and the IDE will automatically recognise them for you.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Connecting to a remote Jupyter notebook<\/h3>\n\n\n\n<p>Alternatively, you can connect to a remote Jupyter notebook by selecting <em>Tools | Add Jupyter Connection<\/em>. You can then choose to start a local Jupyter server, connect to an existing running local Jupyter server, or connect to a Jupyter server using a URL \u2013 all of these options are supported.<\/p>\n\n\n\n<p>Now you have your Jupyter notebook, you need some data!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Importing your data<\/h2>\n\n\n\n<p>Data generally comes in two formats, CSV or database. Let\u2019s look at importing data from a CSV file first.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Importing from a CSV file<\/h3>\n\n\n\n<p><a href=\"https:\/\/pola.rs\/\" target=\"_blank\" rel=\"noopener\">Polars<\/a> and <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/index.html\" target=\"_blank\" rel=\"noopener\">pandas<\/a> are the two most commonly used libraries for importing data into Jupyter notebooks. I\u2019ll give you code for both in this section, and you can check out the documentation for both Polars and pandas and <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/07\/polars-vs-pandas\/\">learn how Polars is different to pandas<\/a>.&nbsp;<\/p>\n\n\n\n<p>You need to ensure your CSV is somewhere in your PyCharm project, perhaps in a folder called `data`. Then, you can invoke import pandas and subsequently use it to read the code in:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import pandas as pd\ndf = pd.read_csv(\"..\/data\/airlines.csv\")<\/pre>\n\n\n\n<p>In this example, <code data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">airlines.csv<\/code> is the file containing the data we want to manipulate. To run this and any code cell in PyCharm, use <em>\u21e7\u23ce <\/em>(macOS) \/ <em>Shift+Enter <\/em>(Windows\/Linux). You can also use the green run arrows on the toolbar at the top.<\/p>\n\n\n\n<p>If you prefer to use Polars, you can use this code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import polars as pl\ndf = pl.read_csv(\"..\/data\/airlines.csv\")<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Importing from a database<\/h3>\n\n\n\n<p>If your data is in a database, as is often the case for internal projects, importing it into a Jupyter notebook will require just a few more lines of code. First, you need to set up your database connection. In this example, we\u2019re using <a href=\"https:\/\/www.jetbrains.com\/help\/idea\/postgresql.html#connect-to-postgresql-database\" target=\"_blank\" rel=\"noopener\">postgreSQL<\/a>.&nbsp;<\/p>\n\n\n\n<p>For pandas, you need to use this code to read the data in:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import pandas as pd\nengine = create_engine(\"postgresql:\/\/jetbrains:jetbrains@localhost\/demo\")\ndf = pd.read_sql(sql=text(\"SELECT * FROM airlines\"),\n                      con=engine.connect())<\/pre>\n\n\n\n<p>And for Polars, it\u2019s this code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import polars as pl\nengine = create_engine(\"postgresql:\/\/jetbrains:jetbrains@localhost\/demo\")\nconnection = engine.connect()\nquery = \"SELECT * FROM airlines\"\ndf = pl.read_database(query, connection)<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">3. Getting acquainted with your data<\/h2>\n\n\n\n<p>Now we\u2019ve read our data in, we can take a look at the DataFrame or `df` as we will refer to it in our code. To print out the DataFrame, you only need a single line of code, regardless of which method you used to read the data in:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">DataFrames<\/h3>\n\n\n\n<p>PyCharm displays your DataFrame as a table firstly so you can explore it. You can scroll horizontally through the DataFrame and click on any column header to order the data by that column. You can click on the <em>Show Column Statistics<\/em> icon on the right-hand side and select <em>Compact<\/em> or <em>Detailed <\/em>to get some helpful statistics on each column of data.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"390\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-3.png\" alt=\"\" class=\"wp-image-536557\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Dynamic charts<\/h3>\n\n\n\n<p>You can use PyCharm to get a dynamic chart of your DataFrame by clicking on the <em>Chart View<\/em> icon on the left-hand side. We\u2019re using pandas in this example, but Polars DataFrames also have the same option.&nbsp;<\/p>\n\n\n\n<p>Click on the <em>Show Series Settings<\/em> icon (a cog) on the right-hand side to configure your plot to meet your needs:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"406\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-4.png\" alt=\"\" class=\"wp-image-536568\"\/><\/figure>\n\n\n\n<p>In this view, you can hover your mouse over your data to learn more about it and easily spot outliers:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"408\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-5.png\" alt=\"\" class=\"wp-image-536579\"\/><\/figure>\n\n\n\n<p>You can do all of this with Polars, too.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Using JetBrains AI Assistant<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.jetbrains.com\/ai\/\" target=\"_blank\" rel=\"noopener\">JetBrains AI Assistant<\/a> has several offerings that can make you more productive when you\u2019re working with Jupyter notebooks inside PyCharm. Let\u2019s take a closer look at how you can use JetBrains AI Assistant to explain a DataFrame, write code, and even explain errors.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Explaining DataFrames<\/h3>\n\n\n\n<p>If you\u2019ve got a DataFrame but are unsure where to start, you can click the purple AI icon on the right-hand side of the DataFrame and select <em>Explain DataFrame<\/em>. JetBrains AI Assistant will use its context to give you an overview of the DataFrame:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"382\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-6.png\" alt=\"\" class=\"wp-image-536590\"\/><\/figure>\n\n\n\n<p>You can use the generated explanation to aid your understanding.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Writing Code&nbsp;<\/h3>\n\n\n\n<p>You can also get JetBrains AI Assistant to help you write code. Perhaps you know what kind of plot you want, but you\u2019re not 100% sure what the code should look like. Well, now you can use JetBrains AI Assistant to help you. Let\u2019s say you want to use \u2018matplotlib\u2019 to create a chart that finds the relationship between \u2018TimeMonthName\u2019 and \u2018MinutesDelayedWeather\u2019. By specifying the column names, we\u2019re giving more context to the request which improves the reliability of the generated code. Try it with the following prompt:<\/p>\n\n\n\n<p><em>Give me code using matplotlib to create a chart which finds the relationship between &#8216;TimeMonthName\u2019 and \u2018MinutesDelayedWeather\u2019 for my dataframe df<\/em><\/p>\n\n\n\n<p>If you like the resulting code, you can use the <em>Insert Snippet at Caret <\/em>button to insert the code and then run it:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import matplotlib.pyplot as plt\n# Assuming your data is in a DataFrame named 'df'\n# Replace 'df' with the actual name of your DataFrame if different\n\n\n# Plotting\nplt.figure(figsize=(10, 6))\nplt.bar(df['TimeMonthName'], df['MinutesDelayedWeather'], color='skyblue')\nplt.xlabel('Month')\nplt.ylabel('Minutes Delayed due to Weather')\nplt.title('Relationship between TimeMonthName and MinutesDelayedWeather')\nplt.xticks(rotation=45)\nplt.grid(axis='y', linestyle='--', alpha=0.7)\nplt.tight_layout()\n\n\nplt.show()<\/pre>\n\n\n\n<p>If you don\u2019t want to open the <em>AI Assistant<\/em> tool window, you can use the AI cell prompt to ask your questions. For example, we can ask the same question here and get the code we need:<\/p>\n\n\n\n<p><strong><img decoding=\"async\" loading=\"lazy\" width=\"624\" height=\"39\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/AD_4nXfazGx_aQ1FpXPhCwSfG0D5ipaLDVbIoWwObso8-BlPOtTon1uSs-JEUtH-ouS_WQqFx8eG2kJ2i9AiW0Y6nViJ291x_7KsOPAfx5rZa9DrM9SikstHGzSJ4JXr3Gw9EwAhVnRnimHVX3B4zUD0MNTBMAE-5.png\"><\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Explaining errors<\/h3>\n\n\n\n<p>You can also get JetBrains AI Assistant to explain errors for you. When you get an error, click <em>Explain with AI<\/em>:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1192\" height=\"232\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-7.png\" alt=\"\" class=\"wp-image-536601\"\/><\/figure>\n\n\n\n<p>You can use the resulting output to further your understanding of the problem and perhaps even get some code to fix it!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Exploring your code<\/h2>\n\n\n\n<p>PyCharm can help you get an overview of your Jupyter notebook, complete parts of your code to save your fingers, refactor it as required, debug it, and even add integrations to help you take it to the next level.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tips for navigating and optimizing your code<\/h3>\n\n\n\n<p>Our Jupyter notebooks can grow large quite quickly, but thankfully you can use PyCharm\u2019s <em>Structure <\/em>view to see all your notebook\u2019s headings by clicking <em>\u23187 <\/em>(macOS) \/ <em>Alt+7<\/em> (Windows\/Linux).<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"592\" height=\"966\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-8.png\" alt=\"\" class=\"wp-image-536612\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Code completion<\/h3>\n\n\n\n<p>Another helpful feature that you can take advantage of when using Jupyter notebooks inside PyCharm is code completion. You get both basic and type-based code completion out of the box with PyCharm, but you can also enable <a href=\"https:\/\/blog.jetbrains.com\/blog\/2024\/04\/04\/full-line-code-completion-in-jetbrains-ides-all-you-need-to-know\/\">Full Line Code Completion<\/a> in PyCharm Professional, which uses a local AI model to provide suggestions. Lastly, JetBrains AI Assistant can also help you write code and discover new libraries and frameworks.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"177\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-9.png\" alt=\"\" class=\"wp-image-536623\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Refactoring<\/h3>\n\n\n\n<p>Sometimes you need to refactor your code, and in that case, you only need to know one keyboard shortcut <em>\u2303T<\/em> (macOS) \/ <em>Shift+Ctrl+Alt+T<\/em> (Windows\/Linux) then you can choose the refactoring you want to invoke. Pick from popular options such as <em>Rename<\/em>, <em>Change Signature,<\/em> and <em>Introduce Variable<\/em>, or lesser-known options such as <em>Extract Method<\/em>, to change your code without changing the semantics:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1231\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-10.png\" alt=\"\" class=\"wp-image-536634\"\/><\/figure>\n\n\n\n<p>As your Jupyter notebook grows, it\u2019s likely that your import statements will also grow. Sometimes you might import a package such as <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">polars<\/code> and <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">numpy<\/code>, but forget that <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">numpy<\/code> is a transitive dependency of the Polars library and as such, we don\u2019t need to import it separately.&nbsp;&nbsp;<\/p>\n\n\n\n<p>To catch these cases and keep your code tidy, you can invoke <em>Optimize Imports<\/em> <em>\u2303\u2325O<\/em> (macOS) \/ <em>Ctrl+Alt+O <\/em>(Windows\/Linux) and PyCharm will remove the ones you don\u2019t need.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Debugging your code<\/h3>\n\n\n\n<p>You might not have used the debugger in PyCharm yet, and that\u2019s okay. Just know that it\u2019s there and ready to support you when you need to better understand some behavior in your Jupyter notebook.&nbsp;<\/p>\n\n\n\n<p>Place a breakpoint on the line you\u2019re interested in by clicking in the gutter or by using <em>\u2318F8 <\/em>(macOS) \/<em> Ctrl+F8<\/em> (Windows\/Linux), and then run your code with the debugger attached with the debug icon on the top toolbar:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1590\" height=\"164\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-11.png\" alt=\"\" class=\"wp-image-536645\"\/><\/figure>\n\n\n\n<p>You can also invoke PyCharm\u2019s debugger in your Jupyter notebook with <em>\u2325\u21e7\u23ce<\/em> (macOS) \/ <em>Shift+Alt+Enter<\/em> (Windows\/Linux). There are some <a href=\"https:\/\/www.jetbrains.com\/help\/pycharm\/running-jupyter-notebook-cells.html#debug-code-in-jupyter-notebooks\" target=\"_blank\" rel=\"noopener\">restrictions<\/a> when it comes to debugging your code in a Jupyter notebook, but please try this out for yourself and share your feedback with us.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding integrations into PyCharm&nbsp;<\/h3>\n\n\n\n<p>IDEs wouldn\u2019t be complete without the integrations you need. PyCharm Professional 2024.2 brings two new integrations to your workflow: <a href=\"https:\/\/www.jetbrains.com\/help\/pycharm\/databricks.html\" target=\"_blank\" rel=\"noopener\">DataBricks<\/a> and <a href=\"https:\/\/www.jetbrains.com\/help\/pycharm\/hugging-face.html\" target=\"_blank\" rel=\"noopener\">HuggingFace<\/a>.<\/p>\n\n\n\n<p>You can enable the integrations with both Databricks and HuggingFace by going to your Settings &lt;kbd&gt;<em>\u2318<\/em>&lt;\/kbd&gt; (macOS) \/ &lt;kbd&gt;<em>Ctrl+Alt+S<\/em>&lt;\/kbd&gt; (Windows\/Linux), selecting <em>Plugins <\/em>and searching for the plugin with the corresponding name on the<em> Marketplace <\/em>tab.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Getting insights from your code<\/h2>\n\n\n\n<p>When analyzing your data, there\u2019s a difference between categorical and continuous variables. Categorical data has a <strong>finite<\/strong> number of discrete groups or categories, whereas continuous data is one <strong>continuous <\/strong>measurement. Let\u2019s look at how we can extract different insights from both the categorical and continuous variables in our airlines dataset.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Continuous variables<\/h3>\n\n\n\n<p>We can get a sense of how continuous data is distributed by looking at measures of the average value in that data and the spread of the data around the average. In normally distributed data, we can use the mean to measure the average and the standard deviation to measure the spread. However, when data is not distributed normally, we can get more accurate information using the median and the interquartile range (this is the difference between the seventy-fifth and twenty-fifth percentiles). Let&#8217;s look at one of our continuous variables to understand the difference between these measurements.<\/p>\n\n\n\n<p>In our dataset, we have lots of continuous variables, but we\u2019ll work with `NumDelaysLateAircraft` to see what we can learn. Let\u2019s use the following code to get some summary statistics for just that column:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df['NumDelaysLateAircraft'].describe()<\/pre>\n\n\n\n<p>Looking at this data, we can see that there is a big difference between the `mean` of ~789 and the \u2018median\u2019 (our fiftieth percentile, indicated by \u201c50%\u201d in the table below) of ~618.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"766\" height=\"576\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-12.png\" alt=\"\" class=\"wp-image-536656\"\/><\/figure>\n\n\n\n<p>This indicates a skew in our variable\u2019s distribution, so let\u2019s use PyCharm to explore it further. Click on the <em>Chart View<\/em> icon at the top left. Once the chart has been rendered, we\u2019ll change the series settings represented by the cog on the right-hand side of the screen. Change your x-axis to `NumDelaysLateAircraft` and your y-axis to `NumDelaysLateAircraft`.&nbsp;<\/p>\n\n\n\n<p>Now drop down the y-axis using the little arrow and select `count`. The final step is to change the chart type to <em>Histogram<\/em> using the icons in the top-right corner:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"359\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-13.png\" alt=\"\" class=\"wp-image-536667\"\/><\/figure>\n\n\n\n<p>Now that we can see the skew laid out visually, we can see that most of the time, the delays are not too excessive. However, we have a number of more extreme delays \u2013 one aircraft is an outlier on the right and it was delayed by 4,509 minutes, which is just over three days!<\/p>\n\n\n\n<p>In statistics, the mean is very sensitive to outliers because it\u2019s a geometric average, unlike the median, which, if you ordered all observations in your variable, would sit exactly in the middle of these values. When the mean is higher than the median, it\u2019s because you have outliers on the right-hand side of the data, the higher side, as we had here. In such cases, the median is a better indicator of the true average delay, as you can see if you look at the histogram.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Categorical variables<\/h3>\n\n\n\n<p>Let\u2019s take a look at how we can use code to get some insights from our categorical variables. In order to get something that\u2019s a little more interesting than just `AirportCode`, we\u2019ll analyze how many aircraft were delayed by weather, `NumDelaysWeather`, in the different months of the year, `TimeMonthName`.<\/p>\n\n\n\n<p>Use this code to group `NumDelaysWeather` with `TimeMonthName`:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">result = df[['TimeMonthName', 'NumDelaysWeather']].groupby('TimeMonthName').sum()\nresult<\/pre>\n\n\n\n<p>This gives us the DataFrame again in table format, but click the <em>Chart View<\/em> icon on the left-hand side of the&nbsp; PyCharm UI to see what we can learn:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"459\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-14.png\" alt=\"\" class=\"wp-image-536678\"\/><\/figure>\n\n\n\n<p>This is okay, but it would be helpful to have the months ordered according to the Gregorian calendar. Let\u2019s first create a variable for the months that we expect:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">month_order = [\n   \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n   \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"\n]<\/pre>\n\n\n\n<p>Now we can ask PyCharm to use the order that we\u2019ve just defined in `month_order`:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Convert the 'TimeMonthName' column to a categorical type with the specified order\ndf[\"TimeMonthName\"] = pd.Categorical(df[\"TimeMonthName\"], categories=month_order, ordered=True)\n\n\n# Now you can group by 'TimeMonthName' and perform sum operation, specifying observed=False\nresult = df[['TimeMonthName', 'NumDelaysWeather']].groupby('TimeMonthName', observed=False).sum()\n\n\nresult<\/pre>\n\n\n\n<p>We then click on the <em>Chart View <\/em>icon once more, but something\u2019s wrong!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"353\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-15.png\" alt=\"\" class=\"wp-image-536689\"\/><\/figure>\n\n\n\n<p>Are we really saying that there were no flights delayed in February? That can\u2019t be right. Let\u2019s check our assumption with some more code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df['TimeMonthName'].value_counts()<\/pre>\n\n\n\n<p>Aha! Now we can see that `Febuary` has been misspelt in our data set, so the correct spelling in our variable name does not match. Let\u2019s update the spelling in our dataset with this code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df[\"TimeMonthName\"] = df[\"TimeMonthName\"].replace(\"Febuary\", \"February\")\ndf['TimeMonthName'].value_counts()<\/pre>\n\n\n\n<p>Great, that looks right. Now we should be able to re-run our earlier code and get a chart view that we can interpret:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"360\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-16.png\" alt=\"\" class=\"wp-image-536700\"\/><\/figure>\n\n\n\n<p>From this view, we can see that there is a higher number of delays during the months of December, January, and February, and then again in June, July, and August. However, we have not standardized this data against the total number of flights, so there may just be more flights in those months, which would cause these results along with an increased number of delays in those summer and winter months.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Sharing your insights and charts<\/h2>\n\n\n\n<p>When your masterpiece is complete, you\u2019ll probably want to export data, and you can do that in various ways with Jupyter notebooks in PyCharm.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Exporting a DataFrame<\/h3>\n\n\n\n<p>You can export a DataFrame by clicking on the down arrow on the right-hand side:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"477\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-17.png\" alt=\"\" class=\"wp-image-536711\"\/><\/figure>\n\n\n\n<p>You have lots of helpful formats to choose from, including SQL, CSV, and JSON:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1131\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-18.png\" alt=\"\" class=\"wp-image-536722\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Exporting charts<\/h3>\n\n\n\n<p>If you prefer to export the interactive plot, you can do that too by clicking on the <em>Export to PNG <\/em>icon on the right-hand side:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"421\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-19.png\" alt=\"\" class=\"wp-image-536733\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Viewing your notebook as a browser<\/h3>\n\n\n\n<p>You can view your whole Jupyter notebook at any time in a browser by clicking the icon in the top-right corner of your notebook:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1112\" height=\"166\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-20.png\" alt=\"\" class=\"wp-image-536744\"\/><\/figure>\n\n\n\n<p>Finally, if you want to export your Jupyter notebook to a Python file, 2024.2 lets you do that too! Right-click on your Jupyter notebook in the<em> Project <\/em>tool window and select <em>Convert to Python File<\/em>. Follow the instructions, and you\u2019re done!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>Using Jupyter notebooks inside <a href=\"https:\/\/www.jetbrains.com\/pycharm\/data-science\/\" target=\"_blank\" rel=\"noopener\">PyCharm Professional<\/a> provides extensive functionality, enabling you to create code faster, explore data easily, and export your projects in the formats that matter to you.&nbsp;<\/p>\n\n\n\n<p>Download PyCharm Professional to try it out for yourself! Get an extended trial today and experience the difference PyCharm Professional can make in your data science endeavors.<\/p>\n\n\n\n<p>Use the promo code \u201c<strong>PyCharmNotebooks<\/strong>\u201d at checkout to activate your free 60-day subscription to PyCharm Professional. The free subscription is available for individual users only.<\/p>\n\n\n    <div class=\"buttons\">\n        <div class=\"buttons__row\">\n                                                <a href=\"https:\/\/jb.gg\/ogc809\" class=\"btn\" target=\"\" rel=\"noopener\">Activate your 60-day trial<\/a>\n                                                    <\/div>\n    <\/div>\n\n\n\n\n","protected":false},"author":1150,"featured_media":510335,"comment_status":"closed","ping_status":"closed","template":"","categories":[952,1401,2347],"tags":[953,7057],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/504467"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/users\/1150"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/comments?post=504467"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/504467\/revisions"}],"predecessor-version":[{"id":613091,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/504467\/revisions\/613091"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media\/510335"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media?parent=504467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/categories?post=504467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/tags?post=504467"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/cross-post-tag?post=504467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}