【问题标题】:How to convert pipe delimited to CSV or JSON如何将分隔的管道转换为 CSV 或 JSON
【发布时间】:2022-01-14 10:02:56
【问题描述】:

我有一个以竖线分隔的 ~4GB txt 文件。我正在尝试将此文本导入 MongoDB,但如您所知,MongoDB 仅支持 JSON 和 CSV 文件。以下是目前为止的代码。

import pandas as pd
import csv
from pymongo import MongoClient

url = "mongodb://localhost:27017"
client = MongoClient(url)
# Creating Database Office
db = client.Office
# Creating Collection Customers
customers = db.Customers

filename = "Names.txt"
data_df = pd.read_fwf(filename, sep="|", engine="python", encoding="latin-1")
fileout = "Names.csv"
output = data_df.to_csv(fileout, sep=",")
print("Finished")
fin = open("Names.csv", "r")
file_data = fin.read()
file_csv = csv.reader(file_data)
Customers.insert_many(file_csv)

输入文件“Name.txt”如下所示

Reg|Name|DOB|Friend|Nationality|Profession^M
1122|Sam|01/01/2001|John|USA|Lawyer^M
2456|George|05/10/1999|Pit|Canada|Engineer^M
5645|Brad|02/06/2000|Adam|UK|Doctor^M

如果提供的文本文件是 CSV,则只需将其导入 MongoDB,或者如果 txt 文件是管道分隔或任何其他分隔,则仅在将文本文件处理为 CSV 文件后将其导入 MongoDB。我在 fileout 中获得的 CSV 文件,当手动导入到 MongoDB 时,结果如下所示。

col1          col2
id    Reg|Name|DOB|Friend|Nationality|Profession
1     1122|Sam|01/01/2001|John|USA|Lawyer
2     2456|George|05/10/1999|Pit|Canada|Engineer
3     5645|Brad|02/06/2000|Adam|UK|Doctor

我想要达到的目标如下所示。这是通过sed 命令完成的。首先,我使用命令将txt文件中的任何“,”替换为“-”

sed -i 's/,/-/g' Names.txt

然后我用“,”替换了管道分隔符:

sed -i 's/|/,/g' Names.txt
col1 col2  col3   col4       col5    col6        col7
id   Reg   Name   DOB        Friend  Nationality Profession
1    1122  Sam    01/01/2001 John    USA         Lawyer
2    2456  George 05/10/1999 Pit     Canada      Engineer
3    5645  Brad   02/06/2000 Adam    UK          Doctor

我知道代码没有做任何事情。但我不知道如何使它工作。

我是所有类型编程的新手,我已经搜索了有关此问题的各种答案以及网站中的各种其他相关问题,但没有一个适合我的需求。

更新

import csv
import json
from pymongo import MongoClient

url = "mongodb://localhost:27017"
client = MongoClient(url)
db = client.Office
customer = db.Customer
jsonArray = []

with open("Names.txt", "r") as csv_file:
    csv_reader = csv.DictReader(csv_file, dialect='excel', delimiter='|', quoting=csv.QUOTE_NONE)
    for row in csv_reader:
        jsonArray.append(row)
    jsonString = json.dumps(jsonArray, indent=1, separators=(",", ":"))
    jsonfile = json.loads(jsonString)
    customer.insert_many(jsonfile)

这是我从 cmets 那里得到一些想法后想出的新代码。但现在唯一的问题是我得到了这个错误。

Traceback (most recent call last):
  File "E:\Anaconda Projects\Mongo Projects\Office Tool\csvtojson.py", line 16, in <module>
    jsonString = json.dumps(jsonArray, indent=1, separators=(",", ":"))
  File "C:\Users\Predator\anaconda3\lib\json\__init__.py", line 234, in dumps
    return cls(
  File "C:\Users\Predator\anaconda3\lib\json\encoder.py", line 201, in encode
    chunks = list(chunks)
MemoryError

【问题讨论】:

  • 顺便说一句,用sed -i 重复覆盖同一个文件效率低下、不优雅且容易出错;很容易将两个sed 脚本合二为一。参见例如stackoverflow.com/questions/7657647/combining-two-sed-commands
  • read_csv(filename, sep='|') 不会按照你的要求去做吗?
  • @tripleee 我已经尝试过 read_csv() 但仍然得到相同的结果。
  • 不要在您的问题中添加寒暄。我们更喜欢帖子严格关注技术内容。一旦你开始收到有用的贡献,你可以通过点赞来表达感激之情,但如果你的问题充满垃圾,机会就会降低。

标签: python mongodb csv pipe pymongo


【解决方案1】:

Pandas read_fwf() 用于数据位于 固定 列中的数据文件。有时它们也可能有一个分隔符(通常是一个竖线字符,以使数据表更易于阅读)。

您可以使用readcsv() 读取管道分隔的文件。只需使用sep='|'

df = pd.read_csv(filename, sep='|')

现在您可以将数据插入到 mongo 集合中,以这种方式将数据帧转换为字典:

Customers.insert_many( df.to_dict(orient='records') )

【讨论】:

  • 这是尝试上述方法 Traceback 时的错误(最近一次调用最后一次):文件“E:\Anaconda Projects\Mongo Projects\SDR Tool\pymongogridfs.py”,第 52 行,在 data_df = pd.read_csv(filename, sep="|", engine="python", encoding="latin-1", quoting=csv.QUOTE_NONE) 文件 "C:\Users\Predator\anaconda3\lib\site- packages\pandas\util_decorators.py",第 311 行,在包装器中返回 func(*args, **kwargs)''''''''''''''''''''''''' '''''''''''''''''' """"""""""""""" pandas.errors.ParserError: 预计第 117481 行有 48 个字段,看到 49
  • 但如果我使用 csv.writer() 将上述管道分隔文件写入新的 csv 文件,则不会弹出错误。
  • 您的管道分隔文件在字段内有一个管道。查看第 117481 行,看看它是否有某种转义字符或引号。您可以尝试使用on_bad_lines='skip'on_bad_lines='warn' 选项使用pandas.read_csv() 加载它。但是还是要看看数据
  • 我更新了代码,但显示内存错误。我认为可以通过 cunk 绕过这个错误,但我不知道如何实现它。
【解决方案2】:

终于找到了解决办法。

我在一个 5GB 的文件上测试了它,虽然速度很慢,但它仍然可以工作。它将管道分隔的 txt 文件中的所有数据导入 MongoDB。

import csv
import json

from pymongo import MongoClient

url_mongo = "mongodb://localhost:27017"
client = MongoClient(url_mongo)
db = client.Office
customer = db.Customer
jsonArray = []
file_txt = "Text.txt"
rowcount = 0
with open(file_txt, "r") as txt_file:
    csv_reader = csv.DictReader(txt_file, dialect="excel", delimiter="|", quoting=csv.QUOTE_NONE)
    for row in csv_reader:
        rowcount += 1
        jsonArray.append(row)
    for i in range(rowcount):
        jsonString = json.dumps(jsonArray[i], indent=1, separators=(",", ":"))
        jsonfile = json.loads(jsonString)
        customer.insert_one(jsonfile)
print("Finished")

感谢大家的想法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-12
    • 2019-03-18
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 2023-03-15
    • 2014-12-09
    • 1970-01-01
    相关资源
    最近更新 更多