In this data analysis tutorial, you will learn how to carry out a Mann-Whitney U test in Python with the packages SciPy and Pingouin. This test is also known as Mann–Whitney–Wilcoxon (MWW), Wilcoxon rank-sum test, or Wilcoxon–Mann–Whitney test and is a non-parametric hypothesis test. Show
Outline of the PostIn this tutorial, you will learn when and how to use this non-parametric test. After that, we will see an example of a situation when the Mann-Whitney U test can be used. The example is followed by how to install the needed package (i.e., SciPy) as well as a package that makes importing data easy and that we can quickly visualize the data to support the interpretation of the results. In the following section, you will learn the 2 steps to carry out the Mann-Whitney-Wilcoxon test in Python. Note, we will also have a look at another package, Pingouin, that enables us to carry out statistical tests with Python. Finally, we will learn how to interpret the results and visualize data to support our interpretation. When to use the Mann-Whitney U testThis test is a rank-based test that can be used to compare values for two groups. If we get a significant result it suggests that the values for the two groups are different. As previously mentioned, the Mann-Whitney U test is equivalent to a two-sample Wilcoxon rank-sum test. Furthermore, we don’t have to assume that our data is following the normal distribution and can decide whether the population distributions are identical. Now, the Mann–Whitney test does not address hypotheses about the medians of the groups. The test assumes that the observations are independent. That is, it is not appropriate for paired observations or repeated measures data. Appropriate data
HypothesesAs with the two samples t-test there are normally two hypothesis:
InterpretationIf the results are significant they can be reported as “The values for men were significantly different from those for women.”, if you are examining differences in values between men and women. When do you use Mann-Whitney U Test?You can use the Mann-Whitney U test when your outcome/dependent variable is either ordinal or continous but not normally distributed. Furthermore, this non-parametric test is used when you want to compare differences between two independent groups (e.g., such as an alternative to the two-sample t-test). To conclude, you should use this test instead of e.g., two-sample t-test using Python if the above information is true for your data. ExampleIn this section, before moving on to how to carry out the test, we will have a quick look at an example when you should use the Mann-Whitney U test. If you, for example, run an intervention study designed to examine the effectiveness of a new psychological treatment to reduce symptoms of depression in adults. Let’s say that you have a total of n=14 participants. Furthermore, these participants are randomized to receive either the treatment or no treatment, at all. In your study, the participants are asked to record the number of depressive episodes over a 1 week period following receipt of the assigned treatment. Here are some example data: Example data In this example, the question you might want to answer is: is there a difference in the number of depressive episodes over a 1 week period in participants receiving the new treatment as in comparison to those receiving no treatment? By inspecting your data, it appears that participants receiving no treatment have more depressive episodes. The crucial question is, however, is this statistically significant? In this example, the outcome variable is number of episodes (count) and, naturally, in this sample, the data do not follow a normal distribution. Note, Pandas was used to create the above histogram. PrerequisitesTo follow this tutorial you will need to have Pandas and SciPy installed. Now, you can get these packages using your favorite Python package manager. For example, installing Python packages with pip can be done as follows:
Note, both Pandas and Pingouin are optional. However, using these packages have, as you will see later, their advantages. Hint, Pandas make data importing easy. If you ever need, you can also use pip to install a specific version of a package. 2 Steps to Perform the Mann-Whitney U test in PythonIn this section, we will go through the steps to carry out the Mann-Whitney U test using Pandas and SciPy. In the
first step, we will get our data. After the data is stored in a dataframe, we will carry out the non-parametric test. </p> <h3><span class="ez-toc-section" id="Step1_Get_your_Data"></span>Step1: Get your Data<span class="ez-toc-section-end"></span></h3> <p>Here’s one way to import data to Python with Pandas:</p> <pre class="wp-block-code"
aria-describedby="shcb-language-2" data-shcb-language-name="Python" data-shcb-language-slug="python"><div><code class="hljs language-python"><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd <span class="hljs-comment"># Getting our data in to a dictionary</span> data = {<span class="hljs-string">'Notrt'</span>:[<span
class="hljs-number">7</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">4</span>, <span class="hljs-number">12</span>, <span class="hljs-number">9</span>, <span class="hljs-number">8</span>], <span class="hljs-string">'Trt'</span>:[<span
class="hljs-number">3</span>, <span class="hljs-number">6</span>, <span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">5</span>, <span class="hljs-number">1</span>]} <span class="hljs-comment"># Dictionary to
Dataframe</span> df = pd.DataFrame(data)</code></div><small class="shcb-language" id="shcb-language-2"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">Python</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">python</span><span
class="shcb-language__paren">)</span></small></pre> <p>In the code chunk above, we created a <a href="https://www.marsja.se/how-to-convert-a-python-dictionary-to-a-pandas-dataframe/" target="_blank" rel="noreferrer noopener">Pandas dataframe from a dictionary</a>. Of course, most of the time we will have our data stored in formats such as CSV or Excel. <span id="ezoic-pub-ad-placeholder-157"
class="ezoic-adpicker-ad"></span><span class="ezoic-ad ezoic-at-0 leader-1 leader-1157 adtester-container adtester-container-157" data-ez-name="marsja_se-leader-1"><span id="div-gpt-ad-marsja_se-leader-1-0" ezaw="250" ezah="250" style="position:relative;z-index:0;display:inline-block;padding:0;width:100%;max-width:1200px;margin-left:auto!important;margin-right:auto!important;min-height:90px;min-width:728px" class="ezoic-ad"><script
data-ezscrex="false" data-cfasync="false" type="text/javascript" style="display:none">if(typeof ez_ad_units != 'undefined'){ez_ad_units.push([[250,250],'marsja_se-leader-1','ezslot_5',157,'0','0'])};__ez_fad_position('div-gpt-ad-marsja_se-leader-1-0');</p> <div class="wp-block-image"><figure class="aligncenter size-full"><div class="ss-on-media-container wp-image-7138"><span class="ss-on-media-image-wrap wp-image-7138"><img width="180" height="329"
src="https://www.marsja.se/wp-content/uploads/2020/09/wide_format_data_to_carry_out_Wilcoxon_rank-sum_test_on_in_Python.jpg" alt="Example data in wide format" class="ss-on-media-img wp-image-7138" srcset="https://www.marsja.se/wp-content/uploads/2020/09/wide_format_data_to_carry_out_Wilcoxon_rank-sum_test_on_in_Python.jpg 180w, https://www.marsja.se/wp-content/uploads/2020/09/wide_format_data_to_carry_out_Wilcoxon_rank-sum_test_on_in_Python-164x300.jpg 164w" sizes="(max-width: 180px) 100vw,
180px"> <div class="ss-on-media-wrapper ss-top-left-on-media ss-small-icons ss-hide-on-mobile ss-with-spacing ss-circle-icons"> <ul class="ss-social-icons-container ss-on-media-pinit"> <li> <div data-ss-ss-link="https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fwww.marsja.se%2Fhow-to-perform-mann-whitney-u-test-in-python-with-scipy-and-pingouin%2F&media=https://www.marsja.se/wp-content/uploads/2020/09/wide_format_data_to_carry_out_Wilcoxon_rank-sum_test_on_in_Python.jpg&description=via%20%40marsja"
class="ss-pinterest-color ss-pinit-button ss-ss-on-media-button" data-ss-ss-location="on_media" data-ss-ss-network-id="pinterest" data-ss-ss-type="share"> <span class="ss-on-media-content"> <svg class="ss-svg-icon" aria-hidden="true" role="img" focusable="false" width="32" height="32" viewbox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M10.625 12.25c0-1.375 0.313-2.5 1.063-3.438 0.688-0.938 1.563-1.438 2.563-1.438 0.813 0 1.438 0.25 1.875 0.813s0.688 1.25 0.688
2.063c0 0.5-0.125 1.125-0.313 1.813-0.188 0.75-0.375 1.625-0.688 2.563-0.313 1-0.563 1.75-0.688 2.313-0.25 1-0.063 1.875 0.563 2.625 0.625 0.688 1.438 1.063 2.438 1.063 1.75 0 3.188-1 4.313-2.938 1.125-2 1.688-4.375 1.688-7.188 0-2.125-0.688-3.875-2.063-5.25-1.375-1.313-3.313-2-5.813-2-2.813 0-5.063 0.875-6.75 2.688-1.75 1.75-2.625 3.875-2.625 6.375 0 1.5 0.438 2.75 1.25 3.75 0.313 0.313 0.375 0.688 0.313 1.063-0.125 0.313-0.25 0.813-0.375 1.5-0.063 0.25-0.188 0.438-0.375 0.5s-0.375 0.063-0.563
0c-1.313-0.563-2.25-1.438-2.938-2.75s-1-2.813-1-4.5c0-1.125 0.188-2.188 0.563-3.313s0.875-2.188 1.625-3.188c0.75-1.063 1.688-1.938 2.688-2.75 1.063-0.813 2.313-1.438 3.875-1.938 1.5-0.438 3.125-0.688 4.813-0.688 1.813 0 3.438 0.313 4.938 0.938 1.5 0.563 2.813 1.375 3.813 2.375 1.063 1.063 1.813 2.188 2.438 3.5 0.563 1.313 0.875 2.688 0.875 4.063 0 3.75-0.938 6.875-2.875 9.313-1.938 2.5-4.375 3.688-7.375 3.688-1 0-1.938-0.188-2.813-0.688-0.875-0.438-1.5-1-1.875-1.688-0.688 2.938-1.125 4.688-1.313
5.25-0.375 1.438-1.25 3.188-2.688 5.25h-1.313c-0.25-2.563-0.188-4.688 0.188-6.375l2.438-10.313c-0.375-0.813-0.563-1.813-0.563-3.063z" /></svg>Save </span> </div> </li> </ul> </div> </span></div></figure></div> <p>See the following posts about how to import data in Python with Pandas:</p> <ul><li><a href="https://www.marsja.se/pandas-read-csv-tutorial-to-csv/" target="_blank" rel="noreferrer noopener">Pandas
Read CSV Tutorial: How to Read and Write</a></li><li><a target="_blank" href="https://www.marsja.se/how-to-read-write-spss-files-in-python-pandas/">How to Read & Write SPSS Files in Python using Pandas</a></li><li><a href="https://www.marsja.se/pandas-excel-tutorial-how-to-read-and-write-excel-files/" target="_blank" rel="noreferrer noopener">Pandas Excel Tutorial: How to Read and Write Excel files</a></li><li><a
href="https://www.marsja.se/how-to-use-pandas-read_html-to-scrape-data-from-html-tables/" target="_blank" rel="noreferrer noopener">How to use Pandas read_html to Scrape Data from HTML Tables</a></li></ul> <figure class="wp-block-image size-large"><div class="ss-on-media-container wp-image-7148"><span class="ss-on-media-image-wrap wp-image-7148"><img width="683" height="1024"
src="https://www.marsja.se/wp-content/uploads/2020/09/how_to_carry_out_wilcoxon_rank-sum_test_in_Python-683x1024.jpg" alt="wilcoxon rank-sum test in python 2 steps" class="ss-on-media-img wp-image-7148"> <div class="ss-on-media-wrapper ss-top-left-on-media ss-small-icons ss-hide-on-mobile ss-with-spacing ss-circle-icons"> <ul class="ss-social-icons-container ss-on-media-pinit"> <li> <div
data-ss-ss-link="https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fwww.marsja.se%2Fhow-to-perform-mann-whitney-u-test-in-python-with-scipy-and-pingouin%2F&media=https://www.marsja.se/wp-content/uploads/2020/09/how_to_carry_out_wilcoxon_rank-sum_test_in_Python-683x1024.jpg&description=via%20%40marsja" class="ss-pinterest-color ss-pinit-button ss-ss-on-media-button" data-ss-ss-location="on_media" data-ss-ss-network-id="pinterest" data-ss-ss-type="share"> <span
class="ss-on-media-content"> <svg class="ss-svg-icon" aria-hidden="true" role="img" focusable="false" width="32" height="32" viewbox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M10.625 12.25c0-1.375 0.313-2.5 1.063-3.438 0.688-0.938 1.563-1.438 2.563-1.438 0.813 0 1.438 0.25 1.875 0.813s0.688 1.25 0.688 2.063c0 0.5-0.125 1.125-0.313 1.813-0.188 0.75-0.375 1.625-0.688 2.563-0.313 1-0.563 1.75-0.688 2.313-0.25 1-0.063 1.875 0.563 2.625 0.625 0.688 1.438 1.063 2.438 1.063
1.75 0 3.188-1 4.313-2.938 1.125-2 1.688-4.375 1.688-7.188 0-2.125-0.688-3.875-2.063-5.25-1.375-1.313-3.313-2-5.813-2-2.813 0-5.063 0.875-6.75 2.688-1.75 1.75-2.625 3.875-2.625 6.375 0 1.5 0.438 2.75 1.25 3.75 0.313 0.313 0.375 0.688 0.313 1.063-0.125 0.313-0.25 0.813-0.375 1.5-0.063 0.25-0.188 0.438-0.375 0.5s-0.375 0.063-0.563 0c-1.313-0.563-2.25-1.438-2.938-2.75s-1-2.813-1-4.5c0-1.125 0.188-2.188 0.563-3.313s0.875-2.188 1.625-3.188c0.75-1.063 1.688-1.938 2.688-2.75 1.063-0.813 2.313-1.438
3.875-1.938 1.5-0.438 3.125-0.688 4.813-0.688 1.813 0 3.438 0.313 4.938 0.938 1.5 0.563 2.813 1.375 3.813 2.375 1.063 1.063 1.813 2.188 2.438 3.5 0.563 1.313 0.875 2.688 0.875 4.063 0 3.75-0.938 6.875-2.875 9.313-1.938 2.5-4.375 3.688-7.375 3.688-1 0-1.938-0.188-2.813-0.688-0.875-0.438-1.5-1-1.875-1.688-0.688 2.938-1.125 4.688-1.313 5.25-0.375 1.438-1.25 3.188-2.688 5.25h-1.313c-0.25-2.563-0.188-4.688 0.188-6.375l2.438-10.313c-0.375-0.813-0.563-1.813-0.563-3.063z" /></svg>Save </span>
</div> </li> </ul> </div> </span></div></figure> <p>Here’s also worth noting that <em>if</em> your data is stored in long format, you will have to subset your data such that you can get the data from each group into two different variables. </p> <h3><span class="ez-toc-section" id="Step_2_Use_the_mannwhitneyu_method_from_SciPy"></span>Step 2: Use the mannwhitneyu method from SciPy:<span
class="ez-toc-section-end"></span></h3> <p>Here’s how to perform the Mann-Whitney U test in Python with SciPy:</p> <pre class="wp-block-code" aria-describedby="shcb-language-3" data-shcb-language-name="Python" data-shcb-language-slug="python"><div><code class="hljs language-python"><span class="hljs-keyword">from</span> scipy.stats <span class="hljs-keyword">import</span> mannwhitneyu <span class="hljs-comment"># Carrying
out the Wilcoxon–Mann–Whitney test</span> results = mannwhitneyu(df[<span class="hljs-string">'Notrt'</span>], df[<span class="hljs-string">'Trt'</span>]) results</code></div><small class="shcb-language" id="shcb-language-3"><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">Python</span> <span class="shcb-language__paren">(</span><span class="shcb-language__slug">python</span><span
class="shcb-language__paren">)</span></small></pre> <p>Notice that we selected the columns, for each group, as x and y parameters to the <code>mannwhitneyu</code> method. If your data, as previously mentioned, is stored in long format (e.g., see image further down below) you can use Pandas <code>query()</code> method to subset the data.</p> <div class="wp-block-image"><figure class="aligncenter size-full"><div
class="ss-on-media-container wp-image-7134"><span class="ss-on-media-image-wrap wp-image-7134"><img width="826" height="51" src="https://www.marsja.se/wp-content/uploads/2020/09/wilcoxon_rank_sum_test_python.jpg" alt="scipy results mann u whitney test in python" class="ss-on-media-img wp-image-7134" srcset="https://www.marsja.se/wp-content/uploads/2020/09/wilcoxon_rank_sum_test_python.jpg 826w, https://www.marsja.se/wp-content/uploads/2020/09/wilcoxon_rank_sum_test_python-480x30.jpg
480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 826px, 100vw"> <div class="ss-on-media-wrapper ss-top-left-on-media ss-small-icons ss-hide-on-mobile ss-with-spacing ss-circle-icons"> <ul class="ss-social-icons-container ss-on-media-pinit"> <li> <div data-ss-ss-link="https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fwww.marsja.se%2Fhow-to-perform-mann-whitney-u-test-in-python-with-scipy-and-pingouin%2F&media=https://www.marsja.se/wp-content/uploads/2020/09/wilcoxon_rank_sum_test_python.jpg&description=results%20from%20the%20wilcoxon%20rank%20sum%20test%20via%20%40marsja"
class="ss-pinterest-color ss-pinit-button ss-ss-on-media-button" data-ss-ss-location="on_media" data-ss-ss-network-id="pinterest" data-ss-ss-type="share"> <span class="ss-on-media-content"> <svg class="ss-svg-icon" aria-hidden="true" role="img" focusable="false" width="32" height="32" viewbox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M10.625 12.25c0-1.375 0.313-2.5 1.063-3.438 0.688-0.938 1.563-1.438 2.563-1.438 0.813 0 1.438 0.25 1.875 0.813s0.688 1.25 0.688
2.063c0 0.5-0.125 1.125-0.313 1.813-0.188 0.75-0.375 1.625-0.688 2.563-0.313 1-0.563 1.75-0.688 2.313-0.25 1-0.063 1.875 0.563 2.625 0.625 0.688 1.438 1.063 2.438 1.063 1.75 0 3.188-1 4.313-2.938 1.125-2 1.688-4.375 1.688-7.188 0-2.125-0.688-3.875-2.063-5.25-1.375-1.313-3.313-2-5.813-2-2.813 0-5.063 0.875-6.75 2.688-1.75 1.75-2.625 3.875-2.625 6.375 0 1.5 0.438 2.75 1.25 3.75 0.313 0.313 0.375 0.688 0.313 1.063-0.125 0.313-0.25 0.813-0.375 1.5-0.063 0.25-0.188 0.438-0.375 0.5s-0.375 0.063-0.563
0c-1.313-0.563-2.25-1.438-2.938-2.75s-1-2.813-1-4.5c0-1.125 0.188-2.188 0.563-3.313s0.875-2.188 1.625-3.188c0.75-1.063 1.688-1.938 2.688-2.75 1.063-0.813 2.313-1.438 3.875-1.938 1.5-0.438 3.125-0.688 4.813-0.688 1.813 0 3.438 0.313 4.938 0.938 1.5 0.563 2.813 1.375 3.813 2.375 1.063 1.063 1.813 2.188 2.438 3.5 0.563 1.313 0.875 2.688 0.875 4.063 0 3.75-0.938 6.875-2.875 9.313-1.938 2.5-4.375 3.688-7.375 3.688-1 0-1.938-0.188-2.813-0.688-0.875-0.438-1.5-1-1.875-1.688-0.688 2.938-1.125 4.688-1.313
5.25-0.375 1.438-1.25 3.188-2.688 5.25h-1.313c-0.25-2.563-0.188-4.688 0.188-6.375l2.438-10.313c-0.375-0.813-0.563-1.813-0.563-3.063z" /></svg>Save </span> </div> </li> </ul> </div> </span></div><figcaption>results from the wilcoxon rank sum test</figcaption></figure></div> <p><span id="ezoic-pub-ad-placeholder-160" class="ezoic-adpicker-ad"></span><span class="ezoic-ad ezoic-at-0 large-mobile-banner-1
large-mobile-banner-1160 adtester-container adtester-container-160" data-ez-name="marsja_se-large-mobile-banner-1"><span id="div-gpt-ad-marsja_se-large-mobile-banner-1-0" ezaw="728" ezah="90" style="position:relative;z-index:0;display:inline-block;padding:0;width:100%;max-width:1200px;margin-left:auto!important;margin-right:auto!important;min-height:90px;min-width:728px" class="ezoic-ad"><script data-ezscrex="false" data-cfasync="false" type="text/javascript"
style="display:none">if(typeof
ez_ad_units != 'undefined'){ez_ad_units.push([[728,90],'marsja_se-large-mobile-banner-1','ezslot_4',160,'0','0'])};__ez_fad_position('div-gpt-ad-marsja_se-large-mobile-banner-1-0');Here’s how to perform the test, using
Now, there are some things to be explained here. First, the Mann-Whitney U Test with the Python Package PingouinAs previously mentioned, we can also install the Python package
Pingouin to carry out the Mann-Whitney U test. Here’s how to perform this test with the
Now, the advantage with using the mwu method is that we will get some additional information (e.g., common language effect size; CLES). Here’s the output:
Interpreting the Results of the Mann-Whitney U testIn this section, we will start off by interpreting the results of the test. Now, this is pretty straight forward. In our example, we can reject H0 because 3 < 7. Furthermore, we have statistically significant evidence at α =0.05 to show that the treatment groups differ in the number of depressive episodes. Naturally, in a real application, we would have set both the H0 and Ha prior to conducting the hypothesis test, as we did here. Visualizing the Data with BoxplotsTo aid the interpretation of our results we can create box plots with Pandas:
In the box plot, we can see that the median is greater for the group that did not get any treatment compared to the group that got treatment. Furthermore, if there were any outliers in our data they would show up as dots in the box plot. If you are interested in more data visualization techniques have a look at the post “9 Data Visualization Techniques You Should Learn in Python”. Visualizing the results of Mann-Whitney U test ConclusionIn this post, you have learned how to perform the Mann-Whitney U test using the Python packages SciPy, Pandas, and Pingouin. Moreover, you have learned when to carry out this non-parametric test both by learning about e.g. when it is appropriate and by an example. After this, you learned how to carry out the test using data from the example. Finally, you have learned how to interpret the results and visualize the data. Note that you preferably should have a larger sample size than in the example of the current post. Of course, you should also make the decision on whether to carry out a one-sided or two-sided test based on theory. In the example of this post, we can assume that going without treatment would mean more depressive episodes. However, in other examples this may not be true. Hope you have learned something and if you have a comment, a suggestion, or anything you can leave a comment below. Finally, I would very much appreciate it if you shared this post across your social media accounts if you found it useful! ReferencesIn this final section, you will find some references and resources that may prove useful. Note, there are both links to blog posts and peer-reviewed articles. Sadly, some of the content here is behind paywalls. Mann-Whitney U Test Mann, H. B.; Whitney, D. R. On a Test of Whether one of Two Random Variables is Stochastically Larger than the Other. Ann. Math. Statist. 18 (1947), no. 1, 50–60. doi:10.1214/aoms/1177730491. https://projecteuclid.org/euclid.aoms/1177730491 Vargha, A., & Delaney, H. D. (2000). A Critique and Improvement of the CL Common Language Effect Size Statistics of McGraw and Wong. Journal of Educational and Behavioral Statistics, 25(2), 101–132. https://doi.org/10.3102/10769986025002101 |