【问题标题】:How to append into a dataframe for many files within a loop如何为循环中的许多文件附加到数据框中
【发布时间】:2019-12-01 10:13:13
【问题描述】:

我正在尝试从许多 docs 文件中提取数据并将它们附加到数据框中。

我编写的代码在处理单个文件时效果很好,但我似乎无法将更多文件附加到数据框中。

import re
import docx2txt
import pandas as pd
import glob

df2=pd.DataFrame()
appennded_data=[]

for file in glob.glob("*.docx"):
    text = docx2txt.process(file)
    a1=text.split()
    d2=a1[37]
    doc2=re.findall("HB0....",text)
    units2=re.findall("00[0-9]...",text) 
    df2['Units']=units2
    df2['Doc']=doc2[0]
    df2['Date']=d2
df2

这给出了一个错误 “值的长度与索引的长度不匹配”

预期输出-

来自 docx1:(我得到的)

Units |  Doc    |   Date

001   |  HB00001 | 23/4/12

002   |  HB00001 | 23/4/12

003   |  HB00001 | 23/4/12

004   |  HB00001 | 23/4/12

005   |  HB00001 | 23/4/12

来自 docx2:

Units |  Doc    |   Date

010   |  HB00002 | 2/6/16

011   |  HB00002 | 2/6/16

最终输出:

Units |  Doc    |   Date

001   |  HB00001 | 23/4/12

002   |  HB00001 | 23/4/12

003   |  HB00001 | 23/4/12

004   |  HB00001 | 23/4/12

005   |  HB00001 | 23/4/12

010   |  HB00002 | 2/6/16

011   |  HB00002 | 2/6/16

任何帮助将不胜感激

【问题讨论】:

  • 你能分享一下你的word doc文件的格式吗?是桌子还是别的什么。如果我们了解这一点,我们会为您提供更好的帮助。
  • 你能检查a1 & doc2的内容看指定的索引是否有效吗?
  • 嗨,它只是一个包含文本的 docx 文件。没有表格或列表或任何东西。文本处理效果很好,我可以只用一个文件创建一个数据框。我只是无法为其他 doc 文件附加数据框。

标签: python pandas loops dataframe


【解决方案1】:

错误是因为列的长度不一样。在处理第二个文件的那一刻,它将尝试将列设置为与第一个文件具有不同长度的值。您不能为列分配与现有列不同的值。

由于您希望最终的 df 具有列 ['Units', 'Doc', 'Date'],您可以做的是创建一个空白 df 并将新结果附加到它。使用ignore_index=True 将其附加到下面而不尝试匹配行索引。

import re
import docx2txt
import pandas as pd
import glob


final_df = pd.DataFrame()

for file in glob.glob("*.docx"):
    text = docx2txt.process(file)
    a1 = text.split()
    d2 = a1[37]
    doc2 = re.findall("HB0....", text)
    units2 = re.findall("00[0-9]...", text)

    # because columns are different length, create them as separate df and concat them
    df2 = pd.DataFrame()
    unit_df = pd.DataFrame(units2)
    doc_df = pd.DataFrame(doc2[0])
    date_df = pd.DataFrame(d2)
    # join them by columns. Any blanks will become NaN, but that's because your data has uneven lengths 
    df2 = pd.concat([df2, unit_df, doc_df, date_df], axis=1)

    # at the end of the loop, append it to the final_df
    final_df = pd.concat([final_df, df2], ignore_index=True)

print(final_df)

【讨论】:

  • 在for循环后将其替换在末尾,但仍然出现相同的错误。\
  • 您希望获得的最终数据框的列名是什么?你希望它是 [units, doc,date,units, doc,date,units, doc,date, ...] 还是 [units, doc,date] ?
【解决方案2】:

我的建议是先用内容构建一个dict,最后创建DataFrame:

import re
import docx2txt
import pandas as pd
import glob

columns = ['Units', 'Doc', 'Date']

data = {col: [] for col in columns}

for file in glob.glob("*.docx"):
    text = docx2txt.process(file)
    a1=text.split()
    d2=a1[37]
    doc2=re.findall("HB0....",text)
    units2=re.findall("00[0-9]...",text) 
    data['Units'].extend(units2)
    data['Doc'].extend(doc2[0])
    data['Date'].extend(d2)

df2 = pd.DataFrame(data)

【讨论】:

  • 返回错误ValueError: arrays must be all be same length
  • 在您的数据中,units2doc2[0]d2 对于所有文件的长度是否相同?
  • 在这种情况下,units2 不能用作此DataFrame 中的列,因为所有列都需要具有相同的长度。除非您想用 NaNs 或其他值填充缺失值 - 但这取决于您的用例
  • 我编辑了我的问题以显示我目前如何获得结果,以及我如何尝试将它们合并为。
  • 我相信你的 RegEx 是错误的。 re.findall("00[0-9]...",text) 不会捕获 010011。请改用re.findall("^([0-9]{3})+", text)
猜你喜欢
  • 2018-04-23
  • 2021-09-22
  • 2017-03-22
  • 2016-07-24
  • 2022-11-13
  • 2018-06-17
  • 2020-10-14
  • 2022-08-15
  • 2021-02-05
相关资源
最近更新 更多