pandas dataframe with 2-rows header and export to csv
It's an ugly hack, but if you needed something to work Right Now(tm), you could write it out in two parts:
>>> pd.DataFrame(df.columns.tolist()).T.to_csv("noblankrows.csv", mode="w", header=False, index=False)
>>> df.to_csv("noblankrows.csv", mode="a", header=False, index=False)
>>> !cat noblankrows.csv
AA,BB,CC
DD,EE,FF
a,b,c1
a,b,c2
a,b,c3
I think this is a bug in to_csv
. If you're looking for workarounds then here's a couple.
To read back in this csv specify the header rows*:
In [11]: csv = "AA,BB,CC
DD,EE,FF
,,
a,b,c1
a,b,c2
a,b,c3"
In [12]: pd.read_csv(StringIO(csv), header=[0, 1])
Out[12]:
AA BB CC
DD EE FF
0 a b c1
1 a b c2
2 a b c3
*strangely this seems to ignore the blank lines.
To write out you could write the header first and then append:
with open('test.csv', 'w') as f:
f.write('\n'.join([','.join(h) for h in zip(*df.columns)]) + '\n')
df.to_csv('test.csv', mode='a', index=False, header=False)
Note the to_csv
part for MultiIndex column here:
In [21]: '\n'.join([','.join(h) for h in zip(*df.columns)]) + '\n'
Out[21]: 'AA,BB,CC\nDD,EE,FF\n'
Use df.to_csv("test.csv", index = False, tupleize_cols=True)
to get the resulting CSV to be:
"('AA', 'DD')","('BB', 'EE')","('CC', 'FF')"
a,b,c1
a,b,c2
a,b,c3
To read it back:
df2=pd.read_csv("test.csv", tupleize_cols=True)
df2.columns=pd.MultiIndex.from_tuples(eval(','.join(df2.columns)))
To get the exact output you wanted:
with open('test.csv', 'a') as f:
pd.DataFrame(np.asanyarray(df.columns.tolist())).T.to_csv(f, index = False, header=False)
df.to_csv(f, index = False, header=False)