Repository: optuna/optuna

Issue:
`study.trials_dataframe()` raises errors when the study does not have any trials.
`study.trials_dataframe()` raises errors when the study does not have any study. I think it is supposed to return empty DataFrame.

**Conditions**
- Optuna version: 0.16.0
- Python version: Python 3.7.2
- OS: macOS 10.13.6
- Machine Learning library to be optimized: N/A

**Code to reproduce**

```python
import optuna
study = optuna.create_study()
study.trials_dataframe()
```

**Error messages, stack traces, or logs**

```shell
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/yanase/pfn/code/optuna/optuna/study.py", line 363, in trials_dataframe
    return pd.DataFrame(records, columns=pd.MultiIndex.from_tuples(columns))
  File "/Users/yanase/.pyenv/versions/optuna-dev/lib/python3.7/site-packages/pandas/core/indexes/multi.py", line 390, in from_tuples
    raise TypeError(msg)
TypeError: Cannot infer number of levels from empty list
```


`study.trials_dataframe()` raises errors when the study does not have any trials.
`study.trials_dataframe()` raises errors when the study does not have any study. I think it is supposed to return empty DataFrame.

**Conditions**
- Optuna version: 0.16.0
- Python version: Python 3.7.2
- OS: macOS 10.13.6
- Machine Learning library to be optimized: N/A

**Code to reproduce**

```python
import optuna
study = optuna.create_study()
study.trials_dataframe()
```

**Error messages, stack traces, or logs**

```shell
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/yanase/pfn/code/optuna/optuna/study.py", line 363, in trials_dataframe
    return pd.DataFrame(records, columns=pd.MultiIndex.from_tuples(columns))
  File "/Users/yanase/.pyenv/versions/optuna-dev/lib/python3.7/site-packages/pandas/core/indexes/multi.py", line 390, in from_tuples
    raise TypeError(msg)
TypeError: Cannot infer number of levels from empty list
```




Discussion:

Resolving patch:
diff --git a/optuna/study.py b/optuna/study.py
--- a/optuna/study.py
+++ b/optuna/study.py
@@ -334,6 +334,10 @@ def trials_dataframe(self, include_internal_fields=False):
         """
         _check_pandas_availability()
 
+        # If no trials, return an empty dataframe.
+        if not len(self.trials):
+            return pd.DataFrame()
+
         # column_agg is an aggregator of column names.
         # Keys of column agg are attributes of FrozenTrial such as 'trial_id' and 'params'.
         # Values are dataframe columns such as ('trial_id', '') and ('params', 'n_layers').


Test patch:
diff --git a/tests/test_study.py b/tests/test_study.py
--- a/tests/test_study.py
+++ b/tests/test_study.py
@@ -408,6 +408,14 @@ def test_study_pickle():
     assert len(study_2.trials) == 20
 
 
+def test_study_trials_dataframe_with_no_trials():
+    # type: () -> None
+
+    study_with_no_trials = optuna.create_study()
+    trials_df = study_with_no_trials.trials_dataframe()
+    assert trials_df.empty
+
+
 @pytest.mark.parametrize('storage_mode', STORAGE_MODES)
 @pytest.mark.parametrize('cache_mode', CACHE_MODES)
 @pytest.mark.parametrize('include_internal_fields', [True, False])