Search code examples
pythonpython-3.xpandastxttabulate

Write a pandas dataframe with different datatypes left aligned into a txt-file


Having the following dataframe:

import pandas as pd

data = {'Column1': ['1e10', '123.1105', '0.5e-2', '0'],
        'Column2': ['String1', 'String3', 101, 'String4']}
df = pd.DataFrame(data)

I want to write it into a txt-file looking like that, where the spaces are really just spaces (no tabs etc.) and every column is aligned left:

------- Data --------
Column1  Column2
1e10     String1
123.1105 String3
0.5e-2   101
0        String4

The closest I have gotten to this is:

from tabulate import tabulate

# Format dataframe into table
table_content = tabulate(df.values.tolist(),tablefmt="plain")

# Write the txt-file
with open("example.txt", "w") as file:
    file.write("------- Data --------")
    file.write(table_content)

Where the output is:

------- Data --------
Column1  Column2
  1e+10  String1
123.111  String3
  0.005  101
  0      String4

The first column though should really be treated as strings: aligned to the left and in the format as specified (this is input for another program that requests it like that). Is there a way to do that efficiently?


Solution

  • You could convert the first column into strings and then use str.ljust:

    import pandas as pd
    
    data = {
        'Column1': ['1e10', '123.1105', '0.5e-2', '0'],
        'Column2': ['String1', 'String3', 101, 'String4']
    }
    df = pd.DataFrame(data)
    df = df.astype(str)
    max_widths = [max(len(str(col)), *df[col].astype(str).apply(len)) for col in df.columns]
    with open('example.txt', 'w') as file:
      file.write('------- Data --------\n')
      header = ' '.join(
          col.ljust(max_widths[i]) for i, col in enumerate(df.columns))
      file.write(header + '\n')
      for index, row in df.iterrows():
        row_str = ' '.join(
            str(value).ljust(max_widths[i]) for i, value in enumerate(row))
        file.write(row_str + '\n')
    

    Output:

    ------- Data --------
    Column1  Column2
    1e10     String1
    123.1105 String3
    0.5e-2   101    
    0        String4