Repository: pandas-dev/pandas

Issue:
col_space parameter in to_html and to_string for dataframe
The col_space parameter in the to_html and to_string functions for dataframe doesn't seem to affect the output. Here's an example using to_html(). Note that the HTML code is identical across the two function calls.

Thanks,
Tej

output.to_html()

<table border="1">
  <thead>
    <tr>
      <th></th>
      <th>nearby = 1      </th>
      <th>nearby = 2      </th>
    </tr>
    </thead>
    <tbody>
    <tr>
      <td><strong>CM_CL</strong></td>
      <td> K2</td>
      <td>  M2</td>
    </tr>
    <tr>
      <td><strong>FI_TY</strong></td>
      <td> M2</td>
      <td> NaN</td>
    </tr>
  </tbody>
</table>


output.to_html(col_space = 2000)

<table border="1">
  <thead>
    <tr>
      <th></th>
      <th>nearby = 1      </th>
      <th>nearby = 2      </th>
    </tr>
    </thead>
    <tbody>
    <tr>
      <td><strong>CM_CL</strong></td>
      <td> K2</td>
      <td>  M2</td>
    </tr>
    <tr>
      <td><strong>FI_TY</strong></td>
      <td> M2</td>
      <td> NaN</td>
    </tr>
  </tbody>
</table>



Discussion:
I can confirm that this bug also affects `to_string()`. Using pandas 0.8.1 I get this: 

```
In [1]: import numpy as np

In [2]: import pandas as pd

In [3]: df = pd.DataFrame(np.random.random(size=(3,3)))

In [4]: print df.to_string(col_space=2)
          0         1         2
0  0.972671  0.735920  0.186650
1  0.092195  0.544714  0.750312
2  0.534684  0.685200  0.887377

In [5]: print df.to_string(col_space=5)
          0         1         2
0  0.972671  0.735920  0.186650
1  0.092195  0.544714  0.750312
2  0.534684  0.685200  0.887377

In [6]: print df.to_string(col_space=10)
          0         1         2
0  0.972671  0.735920  0.186650
1  0.092195  0.544714  0.750312
2  0.534684  0.685200  0.887377

```


Resolving patch:
diff --git a/pandas/core/format.py b/pandas/core/format.py
--- a/pandas/core/format.py
+++ b/pandas/core/format.py
@@ -27,7 +27,7 @@
     columns : sequence, optional
         the subset of columns to write; default None writes all columns
     col_space : int, optional
-        the width of each columns
+        the minimum width of each column
     header : bool, optional
         whether to print column labels, default True
     index : bool, optional
@@ -215,7 +215,7 @@ def _to_str_columns(self, force_unicode=False):
                 fmt_values = self._format_col(i)
                 cheader = str_columns[i]
 
-                max_colwidth = max(_strlen(x) for x in cheader)
+                max_colwidth = max(self.col_space or 0, *(_strlen(x) for x in cheader))
 
                 fmt_values = _make_fixed_width(fmt_values, self.justify,
                                                minimum=max_colwidth)
@@ -434,6 +434,11 @@ def write(self, s, indent=0):
         self.elements.append(' ' * indent + com.pprint_thing(s))
 
     def write_th(self, s, indent=0, tags=None):
+        if (self.fmt.col_space is not None
+            and self.fmt.col_space > 0 ):
+            tags = (tags or "" )
+            tags += 'style="min-width: %s;"' % self.fmt.col_space
+
         return self._write_cell(s, kind='th', indent=indent, tags=tags)
 
     def write_td(self, s, indent=0, tags=None):


Test patch:
diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py
--- a/pandas/tests/test_format.py
+++ b/pandas/tests/test_format.py
@@ -182,6 +182,30 @@ def test_to_string_buffer_all_unicode(self):
         # this should work
         buf.getvalue()
 
+    def test_to_string_with_col_space(self):
+        df = DataFrame(np.random.random(size=(1,3)))
+        c10=len(df.to_string(col_space=10).split("\n")[1])
+        c20=len(df.to_string(col_space=20).split("\n")[1])
+        c30=len(df.to_string(col_space=30).split("\n")[1])
+        self.assertTrue( c10 < c20 < c30 )
+
+    def test_to_html_with_col_space(self):
+        def check_with_width(df,col_space):
+            import re
+            # check that col_space affects HTML generation
+            # and be very brittle about it.
+            html = df.to_html(col_space=col_space)
+            hdrs = [x for x in html.split("\n") if re.search("<th[>\s]",x)]
+            self.assertTrue(len(hdrs) > 0 )
+            for h in hdrs:
+                self.assertTrue("min-width" in h )
+                self.assertTrue(str(col_space) in h )
+
+        df = DataFrame(np.random.random(size=(1,3)))
+
+        check_with_width(df,30)
+        check_with_width(df,50)
+
     def test_to_html_unicode(self):
         # it works!
         df = DataFrame({u'\u03c3' : np.arange(10.)})