我将数据解析为列表并使用pandas构建并写入CSV文件。首先,我的数据被带入一个集合,其中 inv , name , date 都是包含大量条目的列表。然后我使用 concat 将每次迭代通过我解析的数据集连接到CSV文件,如下所示:
counter = True
data = {'Invention': inv, 'Inventor': name, 'Date': date}
if counter is True:
df = pd.DataFrame(data)
df = df[['Invetion', 'Inventor', 'Date']]
else:
df = pd.concat([df, pd.DataFrame(data)])
df = df[['Invention', 'Inventor', 'Date']]
with open('./new.csv', 'a', encoding = utf-8) as f:
if counter is True:
df.to_csv(f, index = False, header = True)
else:
df.to_csv(f, index = False, header = False)
counter = False
对于我解析的所有数据,counter = True语句驻留在我的迭代循环的外,因此它不会每次都被覆盖。
所以这意味着它只运行一次通过我的数据来获取第一个 df 集,然后再将其连接起来。问题是,即使计数器只是第一轮的True,也适用于我的第一个 if-statement ,但是对于我的写入文件不起作用。
无论计数器仅为True一次,都会反复写入标题。当我在计数器为True时交换header = False,那么它永远不会写入标题。
我认为这是因为df以某种方式连接到标题的连接,但除此之外我无法弄清楚逻辑错误。
是否还有另一种方法我也可以只对同一个CSV文件写一次标题?
答案 0 :(得分:4)
如果不看其余的代码,很难说出可能出现的问题。我开发了一些有效的测试数据和逻辑;你可以根据自己的需要进行调整。
请试试这个:
import pandas as pd
early_inventions = ['wheel', 'fire', 'bronze']
later_inventions = ['automobile', 'computer', 'rocket']
early_names = ['a', 'b', 'c']
later_names = ['z', 'y', 'x']
early_dates = ['2000-01-01', '2001-10-01', '2002-03-10']
later_dates = ['2010-01-28', '2011-10-10', '2012-12-31']
early_data = {'Invention': early_inventions,
'Inventor': early_names,
'Date': early_dates}
later_data = {'Invention': later_inventions,
'Inventor': later_names,
'Date': later_dates}
datasets = [early_data, later_data]
columns = ['Invention', 'Inventor', 'Date']
header = True
for dataset in datasets:
df = pd.DataFrame(dataset)
df = df[columns]
mode = 'w' if header else 'a'
df.to_csv('./new.csv', encoding='utf-8', mode=mode, header=header, index=False)
header = False
或者,您可以连接循环中的所有数据并在结尾处写出数据帧:
df = pd.DataFrame(columns=columns)
for dataset in datasets:
df = pd.concat([df, pd.DataFrame(dataset)])
df = df[columns]
df.to_csv('./new.csv', encoding='utf-8', index=False)
如果您的代码无法符合此API,则可以放弃在to_csv中完全写入标头。您可以检测输出文件是否存在,如果不存在,则首先将标头写入其中:
import os
fn = './new.csv'
if not os.exists(fn):
with open(fn, mode='w', encoding='utf-8') as f:
f.write(','.join(columns) + '\n')
# now append the dataframe without a header
df.to_csv(fn, encoding='utf-8', mode='a', header=False, index=False)
答案 1 :(得分:0)
我发现了同样的问题。如果数据框已完成并且无需执行任何教程之外的任何工作,则熊猫 dataframe to csv 可以正常工作。
但是,如果我们的程序正在产生结果并追加结果,则似乎发现了重复标头写入问题
为解决此问题,请考虑以下功能:
def write_data_frame_to_csv_2(dict, path, header_list):
df = pd.DataFrame.from_dict(data=dict, orient='index')
filename = os.path.join(path, 'results_with_header.csv')
if os.path.isfile(filename):
mode = 'a'
header = 0
else:
mode = 'w'
header = header_list
with open(filename, mode=mode) as f:
df.to_csv(f, header=header, index_label='model')
如果文件不存在,我们将使用写入模式,并且标头等于标头列表。如果为假,并且文件存在,我们将使用append和header更改为0。
该函数接收一个简单的字典作为参数,就我而言,我使用了:
model = { 'model_name':{'acc':0.9,
'loss':0.3,
'tp':840,
'tn':450}
}
多次使用ipython控制台中的函数形式会产生预期的结果:
write_data_frame_to_csv_2(model, './', header_list)
Csv生成:
model,acc,loss,tp,tn
model_name,0.9,0.3,840,450
model_name,0.9,0.3,840,450
model_name,0.9,0.3,840,450
model_name,0.9,0.3,840,450
让我知道是否有帮助。 编码愉快!
答案 2 :(得分:0)
如果您要使用索引遍历API调用以在csv文件中添加数据,只需在设置标头属性之前添加此检查。
<Field name="address">
{({
field, // { name, value, onChange, onBlur }
}) => {
values.address = values.mainAddress;
return (
<div>
<input
{...field}
type="text"
placeholder="Address"
/>
</div>
);
}}
</Field>