фрейм данных pandas с заголовком в 2 строки и экспортом в csv
У меня есть фрейм данных
df = pd.DataFrame(columns = ["AA", "BB", "CC"])
df.loc[0]= ["a", "b", "c1"]
df.loc[1]= ["a", "b", "c2"]
df.loc[2]= ["a", "b", "c3"]
Мне нужно добавить строку secod в заголовок
df.columns = pd.MultiIndex.from_tuples(zip(df.columns, ["DD", "EE", "FF"]))
Мой df теперь
AA BB CC
DD EE FF
0 a b c1
1 a b c2
2 a b c3
Но когда я пишу этот фрейм данных в csv-файл
df.to_csv("test.csv", index = False)
Я получаю на одну строку больше, чем ожидалось
AA,BB,CC
DD,EE,FF
,,
a,b,c1
a,b,c2
a,b,c3
4 ответов:
Это уродливый хак, но если вам нужно что-то работать прямо сейчас (tm), вы можете написать его в двух частях:
>>> 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
Я думаю, что это ошибка в
to_csv. Если вы ищете обходные пути, то вот пара.Для чтения обратно в этом csv укажите строки заголовка*:
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*странно, что это, кажется, игнорирует пустые строки.
Для записи вы можете сначала написать заголовок, а затем добавить:
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)Обратите внимание на часть
to_csvдля столбца MultiIndex здесь:In [21]: '\n'.join([','.join(h) for h in zip(*df.columns)]) + '\n' Out[21]: 'AA,BB,CC\nDD,EE,FF\n'
Используйте
df.to_csv("test.csv", index = False, tupleize_cols=True), чтобы получить результирующий CSV:"('AA', 'DD')","('BB', 'EE')","('CC', 'FF')" a,b,c1 a,b,c2 a,b,c3Чтобы прочитать его обратно:
df2=pd.read_csv("test.csv", tupleize_cols=True) df2.columns=pd.MultiIndex.from_tuples(eval(','.join(df2.columns)))Чтобы получить точный результат, который вы хотели:
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)
Построение поверх решения @DSM:
Если вам нужно (как я сделал) применить тот же хак для экспорта в excel , основное изменение, необходимое (помимо ожидаемых различий с методом to_excel), заключается в фактическом удалении мультииндекса, используемого для меток столбцов...
Это потому, что .to_excel не поддерживает запись df, имеющего мультииндекс для столбцов, но без индекса (предоставление index=False методу .to_excel) в отличие от. to_csv
В любом случае, вот как это будет выглядеть:
>>> writer = pd.ExcelWriter("noblankrows.xlsx") >>> headers = pd.DataFrame(df.columns.tolist()).T >>> headers.to_excel( writer, header=False, index=False) >>> df.columns = pd.Index(range(len(df.columns))) # that's what I was referring to... >>> df.to_excel( writer, header=False, index=False, startrow=len(headers)) >>> writer.save() >>> pd.read_excel("noblankrows.xlsx").to_csv(sys.stdout, index=False) AA,BB,CC DD,EE,FF a,b,c1 a,b,c2 a,b,c3
Comments