将pandas DataFrame附加到具有固定标头的csv



我想迭代地将pandas DataFrames附加到csv文件中。这通常不是问题。但是,DataFrames可能不具有所有列。因此,简单地追加会将DataFrame追加到错误的列中。

我从开始

with open('test.csv', 'w') as output:
writer = csv.writer(output, delimiter=',')
writer.writerow(['a','b', 'c'])

例如,我添加了DataFrame df

a   b   c
0   2   2.0 3
1   2   NaN 3

使用命令

df = pd.DataFrame([{'a':2, 'b':2, 'c':3}, {'a':2, 'c':3}])
df.to_csv('test.csv', index = False, header = False, mode = 'a') 

然而,我想要附加的下一个DataFrame可能看起来像

a   c
0   1   1
1   1   1

当我再次附加它时,我不想写标题,因为它已经存在了。与以前一样(如预期(不起作用:

df =pd.DataFrame([{'a':1, 'c':1}, {'a':1, 'c':1}])
df.to_csv('test.csv', index = False, header = False, mode = 'a')

它产生

a   b   c
0   2   2.0 3.0
1   2   NaN 3.0
2   1   1.0 NaN
3   1   1.0 NaN

当然,我可以将现有的csv导入DataFrame,然后附加并覆盖旧文件:

file = pd.read_csv('test.csv')
df =pd.DataFrame([{'a':1, 'c':1}, {'a':1, 'c':1}])
file = file.append(df)
file.to_csv('test.csv', index = False, header = True)
pd.read_csv('test.csv')

这正是我想要的

a   b   c
0   2   2.0 3
1   2   NaN 3
2   1   NaN 1
3   1   NaN 1

但是,当我多次重复这个过程时,总是读取整个csv文件并在panda中附加并覆盖csv肯定会影响性能。我想把我的中间结果写到csv中,因为如果我只附加在pandas DataFrame中,然后发生错误,所有聚合的数据都会丢失。我的问题有更好的解决方案吗?

我还尝试添加新的空列,但它们在最后被添加,这没有帮助,但可能有助于找到性能更好的解决方案。

def append_to_csv(df, file):
if not os.path.exists(file):
pd.to_csv(file, index = False, header = True)
else:
with open(file) as f:
header = next(csv.reader(f))
columns = df.columns
for column in set(header) - set(columns):
df[column] = np.nan
df.to_csv(file, index = False, header = False, mode = 'a')

您总是可以将一个空列附加到df,如下所示:

In [958]: df['b']=''

然后像一样重新构造df

In [959]: df = df[['a','b','c']]
In [960]: df
Out[960]: 
a b  c
0  1    1
1  1    1

现在,将其写入csv。

In [961]: df.to_csv('test.csv', index = False, header = False, mode = 'a')

如果这有帮助,请告诉我。

为了完整起见,我在这里添加了使用Mayank Porwal答案的函数:每当您想将DataFrame附加到具有指定标头的csv时。如果你想允许新的列(不包含在标题中(,你需要修改函数。

def append_to_csv(df, file):
with open(file) as f:
header = next(csv.reader(f))
columns = df.columns
for column in set(header) - set(columns):
df[column] = ''
df = df[header]
df.to_csv(file, index = False, header = False, mode = 'a')

最新更新