DataFrame iterrows() 和 .to_csv:逐行写入
Posted
技术标签:
【中文标题】DataFrame iterrows() 和 .to_csv:逐行写入【英文标题】:DataFrame interrows() and .to_csv: Writing row by row 【发布时间】:2019-12-18 01:43:43 【问题描述】:我正在使用以下脚本来
将函数应用于 DataFrame 的每一行中的列 将该函数的返回值写入 DataFrame 的两个新列中 不断将 DataFrame 写入 *.csv我想了解是否有更好的方法来运行以下计算:
df = 500 行 20 列的 DataFrame
for index, row in df.iterrows():
df.loc[index, 'words'], df.loc[index, 'count'] = transcribe(df.loc[index, 'text'])
df.to_csv('out.csv', encoding='utf-8', index=False)
目前,脚本每次(对于每一行)都将完整的 df 数据帧输出为 *.csv,包括在此之前计算的行“words”和“counts”的添加值。我想知道,是否也可以逐行完整地编写,即仅输出 csv 中完整的那些行。
谢谢!
【问题讨论】:
使用我当前的功能,所描述的附加模式具有多次附加完整数据帧的效果。 【参考方案1】:我不明白你为什么要逐行而不是在最后写入整个数据帧,但这里有一个解决你问题的方法:在追加模式下写入数据帧的切片(即当前行) ,仅添加第一行的标题:
is_first_row = True
for index, row in df.iterrows():
df.loc[index, 'words'], df.loc[index, 'count'] = transcribe(df.loc[index, 'text'])
df.loc[index:index].to_csv('out.csv', encoding='utf-8', index=False, mode='a', header=is_first_row)
is_first_row = False
根据脚本可能被中断的评论更新: 在这种情况下,您可能希望通过检查文件是否已存在或是否是新文件来确定是否写入标头:
with open('out.csv', encoding='utf-8', mode='a') as f:
for index, row in df.iterrows():
df.loc[index, 'words'], df.loc[index, 'count'] = transcribe(df.loc[index, 'text'])
df.loc[index:index].to_csv(f, index=False, header=f.tell()==0)
【讨论】:
有一个很长的列表,我正在应用一个 API 作为函数。每当脚本中断时,我就会沉没成本并且没有输出。这就是为什么我喜欢一行一行地写。 @Christopher:我明白。请参阅我对此案例的更新答案。如果您的脚本被中断,您还将丢失is_first_row
的当前值,因此您必须动态确定标头条件。
作为替代方案,您可能希望将整个逻辑包装在 try
块中,并将数据帧写入其中的 finally
部分。
最后一个问题:假设我有一个池/多线程进程,其中每 4 行都被计算。如何更改上面的脚本,以便每行始终需要 4 行来应用函数并写入 csv?
我不确定你会如何实现它。如果每个线程都有自己的 iterrow() 循环,您可以按原样使用该解决方案,但问题是 4 个线程写入一个文件:有关详细信息,请参阅here。因此,也许您需要一个队列,其中所有 4 个线程都将其结果推入其中,一个线程从队列中获取值,将它们附加到数据帧并将其写回(如上所示)。以上是关于DataFrame iterrows() 和 .to_csv:逐行写入的主要内容,如果未能解决你的问题,请参考以下文章
DataFrame iterrows() 和 .to_csv:逐行写入