фрейм данных 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
953   4  

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

    Ничего не найдено.