[MRG+1] fix P/R/F for truncated range(n_labels)
diff --git a/doc/whats_new/v0.20.rst b/doc/whats_new/v0.20.rst
index 5b15eddbf514a..1fbc356b0f088 100644
--- a/doc/whats_new/v0.20.rst
+++ b/doc/whats_new/v0.20.rst
@@ -246,6 +246,10 @@ Decomposition, manifold learning and clustering
 
 Metrics
 
+- Fixed a bug in :func:`metrics.precision_precision_recall_fscore_support`
+  when truncated `range(n_labels)` is passed as value for `labels`.
+  :issue:`10377` by :user:`Gaurav Dhingra <gxyd>`.
+
 - Fixed a bug due to floating point error in :func:`metrics.roc_auc_score` with
   non-integer sample weights. :issue:`9786` by :user:`Hanmin Qin <qinhanmin2014>`.
 
diff --git a/sklearn/metrics/classification.py b/sklearn/metrics/classification.py
index 8124b7d4457d9..77a9653250876 100644
--- a/sklearn/metrics/classification.py
+++ b/sklearn/metrics/classification.py
@@ -1072,6 +1072,7 @@ def precision_recall_fscore_support(y_true, y_pred, beta=1.0, labels=None,
                 raise ValueError('All labels must be in [0, n labels). '
                                  'Got %d < 0' % np.min(labels))
 
+        if n_labels is not None:
             y_true = y_true[:, labels[:n_labels]]
             y_pred = y_pred[:, labels[:n_labels]]
 
diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py
index c1952ddbbc7de..0f0769017ff12 100644
--- a/sklearn/metrics/tests/test_classification.py
+++ b/sklearn/metrics/tests/test_classification.py
@@ -197,6 +197,14 @@ def test_precision_recall_f_extra_labels():
         assert_raises(ValueError, recall_score, y_true_bin, y_pred_bin,
                       labels=np.arange(-1, 4), average=average)
 
+    # tests non-regression on issue #10307
+    y_true = np.array([[0, 1, 1], [1, 0, 0]])
+    y_pred = np.array([[1, 1, 1], [1, 0, 1]])
+    p, r, f, _ = precision_recall_fscore_support(y_true, y_pred,
+                                                 average='samples',
+                                                 labels=[0, 1])
+    assert_almost_equal(np.array([p, r, f]), np.array([3 / 4, 1, 5 / 6]))
+
 
 @ignore_warnings
 def test_precision_recall_f_ignored_labels():

#### What does this implement/fix? Explain your changes.

Fixes https://github.com/scikit-learn/scikit-learn/issues/10307

for ex. if n_labels = 5, then passing labels = [0, 1, 2]
will give results similar to labels = [0, 1, 2, 3, 4], neglecting
the value of labels.

Currently in master branch:
```python
>>> y_true = np.array([[0, 1, 1], [1, 0, 0]])
>>> y_pred = np.array([[1, 1, 1], [1, 0, 1]])
>>> precision_recall_fscore_support(y_true, y_pred, average='samples', labels=[0, 1])
(0.58333333333333326, 1.0, 0.73333333333333339, None)
>>> precision_recall_fscore_support(y_true, y_pred, average='samples', labels=[1, 0])
(0.75, 1.0, 0.83333333333333326, None)
```

I'm not sure if this will require any changes to test_common, since labels=[0, 1] and labels=[1, 0] should give the same result for `average='samples'` (atleast for `average='samples'`, haven't thought about other averages), this is similar to commutative property w.r.t. `labels`.