簡體   English   中英

如何在pandas df中為csv write插入第二個標題行

[英]How to insert a second header row in pandas df for csv write

我有一個非常大的熊貓df我寫到csv。 我需要添加包含數據類型的第二個標題行。 以下代碼有效,但在CSV中產生第三個意外的空行:

#! /usr/bin/env python
import pandas as pd

df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))

# get count of header columns, add REAL for each one
types_header_for_insert = list(df.columns.values)
for idx, val in enumerate(types_header_for_insert):
    types_header_for_insert[idx] = 'REAL'

# count number of index columns, then add STRING for each one
index_count = len(df.index.names)
for idx in range(0, index_count):
    df.reset_index(level=0, inplace=True)
    types_header_for_insert.insert(0, 'STRING')

# insert the new types column
df.columns = pd.MultiIndex.from_tuples(zip(df.columns, types_header_for_insert))

print df.columns.values

df.to_csv("./test.csv", index=False)

輸出:

index,A,B
STRING,REAL,REAL
,,
0,1,2
1,3,4

我怎樣才能擺脫這個額外的空白行? 它從何而來?

我最后使用了一個解決方法(a)將原始標題寫入csv(b)用第二個標題行替換標題並將整個df附加到第一個文件:

# write the header to the file only
pd.DataFrame(data=[df.columns]).to_csv("outfile.csv", header=False, index=False)

# now replace header
types_header_for_insert = list(df.columns.values)
for idx, val in enumerate(df.columns.values):
    if df[val].dtype == 'float64':
        types_header_for_insert[idx] = 'REAL'

    elif self.grouped[val].dtype == 'int64':
        types_header_for_insert[idx] = 'INTEGER'

    else:
        types_header_for_insert[idx] = 'STRING'

df.columns = types_header_for_insert

# append the whole df with new header
df.to_csv("outfile.csv", mode="a", float_format='%.3f', index=False)

我認為這是bug,見開放問題6618

也許幫助小技巧 - 在第一行之前將types_header_for_insert添加到數據:

#! /usr/bin/env python
import pandas as pd

df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))

# get count of header columns, add REAL for each one
types_header_for_insert = list(df.columns.values)
for idx, val in enumerate(types_header_for_insert):
    types_header_for_insert[idx] = 'REAL'

# count number of index columns, then add STRING for each one
index_count = len(df.index.names)
for idx in range(0, index_count):
    df.reset_index(level=0, inplace=True)
    types_header_for_insert.insert(0, 'STRING')

# insert the new types column
#df.columns = pd.MultiIndex.from_tuples(zip(df.columns, types_header_for_insert))

#set new value to dataframe
df.loc[-1]  = types_header_for_insert

#sort index 
df = df.sort_index()
print df
#     index     A     B
#-1  STRING  REAL  REAL
# 0       0     1     2
# 1       1     3     4

print df.to_csv(index=False)
#index,A,B
#STRING,REAL,REAL
#0,1,2
#1,3,4

編輯

在大df中你可以使用append

#empty df with column from df
df1 = pd.DataFrame(columns = df.columns)
#create series from types_header_for_insert
s = pd.Series(types_header_for_insert, index=df.columns)
print s
index    STRING
A          REAL
B          REAL
dtype: object

df1 = df1.append(s, ignore_index=True).append(df, ignore_index=True)
print df1
    index     A     B
0  STRING  REAL  REAL
1       0     1     2
2       1     3     4

print df1.to_csv(index=False)
index,A,B
STRING,REAL,REAL
0,1,2
1,3,4

在Python 3中, MultiIndex.from_tuples()失敗,類型為'zip'的對象沒有len() 但是,在list()包裝zip不起作用。 考慮在Python 2中嘗試它:

df.columns = pd.MultiIndex.from_tuples(list(zip(df.columns, types_header_for_insert)))

print df.columns.values

df.to_csv("./test.csv", index=False)

#   index    A    B
#  STRING REAL REAL
#       0    1    2
#       1    3    4

或者,使用列表理解來環繞zip

data = [df.columns, types_header_for_insert]
newcolumns = [tuple(i[j] for i in data) for j in range(min(len(l) for l in data))]
df.columns = pd.MultiIndex.from_tuples(newcolumns)

print df.columns.values

df.to_csv("./test.csv", index=False)

#   index    A    B
#  STRING REAL REAL
#       0    1    2
#       1    3    4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM