StandardScaler and PolynomialFeatures fail on zero-feature inputs during fit (should become passthrough)

### Describe the bug

If you use StandardScaler or PolynomialFeatures (or other transformers, these are the two that hit me first) as elements in  a complex pipeline, an issue comes up if you ever fit these transformers on data that has no features (empty data). This happens a lot when you build a complex pipeline and you don't know what the features will be in advance. For example, in reinforcement learning problems, some problems will have context features while others won't, and we need pipelines for both the action and context features which are then concatenated (using FeatureUnion). My current workaround is that when I try to fit my pipeline, if it fails, it eliminates StandardScalers and PolynomialFeatures because they are a part of the context pipeline and we don't have context features for this problem, then fit again. 

### Steps/Code to Reproduce


from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.pipeline import Pipeline

pipeline = Pipeline([
    ('polynomial', PolynomialFeatures()),
    ('fully_transformed_action_and_context', StandardScaler()),
])

pipeline.fit([[]])

### Expected Results

No error is thrown. Pipeline becomes equivalent to passthrough.

### Actual Results

  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sklearn/pipeline.py", line 390, in fit
    Xt = self._fit(X, y, **fit_params_steps)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sklearn/pipeline.py", line 348, in _fit
    X, fitted_transformer = fit_transform_one_cached(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/joblib/memory.py", line 355, in __call__
    return self.func(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sklearn/pipeline.py", line 893, in _fit_transform_one
    res = transformer.fit_transform(X, y, **fit_params)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sklearn/base.py", line 847, in fit_transform
    return self.fit(X, **fit_params).transform(X)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sklearn/preprocessing/_polynomial.py", line 287, in fit
    _, n_features = self._validate_data(X, accept_sparse=True).shape
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sklearn/base.py", line 561, in _validate_data
    X = check_array(X, **check_params)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sklearn/utils/validation.py", line 806, in check_array
    raise ValueError(
ValueError: Found array with 0 feature(s) (shape=(1, 0)) while a minimum of 1 is required.


### Versions

```shell
System:
    python: 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18)  [Clang 6.0 (clang-600.0.57)]
executable: /usr/local/bin/python3.8
   machine: macOS-10.15.7-x86_64-i386-64bit
Python dependencies:
          pip: 20.0.2
   setuptools: 41.2.0
      sklearn: 1.0.1
        numpy: 1.19.5
        scipy: 1.4.1
       Cython: 0.29.16
       pandas: 1.4.0
   matplotlib: 3.2.1
       joblib: 0.14.1
threadpoolctl: 3.0.0
Built with OpenMP: True
```

COMMENT:
> Handling empty data is similar to working with any identity object (zero for summation or one for multiplication).

Your pipeline is made of steps requiring statistics (mean and std. dev.) that are not defined for empty arrays. So this is not straightforward to me that identity should be the "expected" default.

> which is kind of the point for the Pipeline API.

The primary point of the pipeline API is to transform data through a sequence of transformers without the hassle to store intermediate data structure and doing the plumbing between transformers.

> Other transformers handle empty data just fine

I am surprised. Usually, all our estimators are using `check_array` and most of the time, we required a minimum of 1 feature using the default value of `ensure_min_features`. For instance, a `StandardScaler` would reject an empty array:

```python
In [3]: from sklearn.preprocessing import StandardScaler

In [4]: StandardScaler().fit([[]])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-512e4321a403> in <module>
----> 1 StandardScaler().fit([[]])

~/Documents/packages/scikit-learn/sklearn/preprocessing/_data.py in fit(self, X, y, sample_weight)
    807         # Reset internal state before fitting
    808         self._reset()
--> 809         return self.partial_fit(X, y, sample_weight)
    810 
    811     def partial_fit(self, X, y=None, sample_weight=None):

~/Documents/packages/scikit-learn/sklearn/preprocessing/_data.py in partial_fit(self, X, y, sample_weight)
    842         """
    843         first_call = not hasattr(self, "n_samples_seen_")
--> 844         X = self._validate_data(
    845             X,
    846             accept_sparse=("csr", "csc"),

~/Documents/packages/scikit-learn/sklearn/base.py in _validate_data(self, X, y, reset, validate_separately, **check_params)
    575             raise ValueError("Validation should be done on X, y or both.")
    576         elif not no_val_X and no_val_y:
--> 577             X = check_array(X, input_name="X", **check_params)
    578             out = X
    579         elif no_val_X and not no_val_y:

~/Documents/packages/scikit-learn/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name)
    903         n_features = array.shape[1]
    904         if n_features < ensure_min_features:
--> 905             raise ValueError(
    906                 "Found array with %d feature(s) (shape=%s) while"
    907                 " a minimum of %d is required%s."

ValueError: Found array with 0 feature(s) (shape=(1, 0)) while a minimum of 1 is required by StandardScaler.
```

So since that `Pipeline` just delegates the validation, it means that you want to enforce `ensure_min_features=0` to every transformer. It means that internally we should treat this specific case where we should return an empty `X`.

So in short, you are requesting that we put a 

```python
if X.empty():
    return X
```

in all the scikit-learn estimators.

I am under the impression that this is not the proper way to go.

Labels: Bug, module:preprocessing