【问题标题】:Python 3 file handling txt or csvPython 3 文件处理 txt 或 csv
【发布时间】:2018-03-18 15:50:59
【问题描述】:

我有一个文件 txt/csv 文件,其分隔符为“~”每个值都由分隔符分隔,但分隔符之间的值也有“\n”字符。我希望将每个值的输出文件放在每个包含换行符的单元格中。我该怎么做?

我的文件如下所示:

1~2~3~4~5~6~7~8~9~10~11~12~13~14~15~16~17~18~19~20~21~22~23~24~25~26~27~28~29~30~31~32~33~34~35~36~37~38~39~40~
284913111067~284913111068~284913111069~284913111070~284913111071~284913111072~284913111073~284913111074~284913111075~284913111076~284913111077~284913111078~284913111079~284913111080~284913111081~284913111082~284913111083~284913111084~284913111085~284913111086~284913111087~284913111088~284913111089~284913111090~284913111091~284913111092~284913111093~284913111094~284913111095~284913111096~284913111097~284913111098~284913111099~284913111100~284913111101~284913111102~284913111103~284913111104~284913111105~284913111106~
MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~MSS~SA~SA~SA~SA~SA~SA~SA~SA~SA~SA~SA~SA~SA~SA~SA~
U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~U~NE~NE~NE~NE~NE~NE~NE~NE~U~NE~U~NE~U~U~U~
0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~
284913380481;284913380482;284913380483;284913380484~284913380485;284913380486;284913380487;284913380488~284913380489;284913380490;284913380491;284913380492~284913380493;284913380494;284913380495;284913380496~284913380497;284913380498;284913380499;284913380500~284913380501;284913380502;284913380503;284913380504~284913380505;284913380506;284913380507;284913380508~284913380509;284913380510;284913380511;284913380512~284913380513;284913380514;284913380515;284913380516~284913380517;284913380518;284913380519;284913380520~284913380521;284913380522;284913380523;284913380524~284913380525;284913380526;284913380527;284913380528~284913380529;284913380530;284913380531;284913380532~284913380533;284913380534;284913380535;284913380536~284913380537;284913380538;284913380539;284913380540~284913380541;284913380542;284913380543;284913380544~284913380545;284913380546;284913380547;284913380548~284913380549;284913380550;284913380551;284913380552~284913380553;284913380554;284913380555;284913380556~284913380557;284913380558;284913380559;284913380560~284913380561;284913380562;284913380563;284913380564~284913380565;284913380566;284913380567;284913380568~284913380569;284913380570;284913380571;284913380572~284913380573;284913380574;284913380575;284913380576~284913380577;284913380578;284913380579;284913380580~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~Not Applicable~
--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~xbchbshfbjdzbuygeyrgjdzhzuihewu45hriuy78646213wsdcvbgdreser
bhbhgv

hbhdbfhzdxf   )_+)()*^

fddgfbduhygfdhxzxcvbnm


lkjhg
 gggffd bgdd fds aqwe rtyi opp,./'; []=-0987654321       



<>?":{}|+_)(*&^%$#@!


nhgdytsgfcusifu7fygtsygfyfrdfjhsd5e56
skjbftys
sfkndytfdtwsy6
trd
dgrdy
126;7';''',./';l[]]-=0

jhou8rdsj4nrzbwe4red
sb resyf
ASCVmnhgfstafdtg,./';[]=-0987654321<>?":{AASDFDFqeffrewrttg!@#$%^~--~--~--~

从上面的文件可以看出,分隔符之间的值有换行符 我的输出应该在 csv 中,每个值都在单个单元格中,例如:

1.....40
mss ...SA

【问题讨论】:

  • 请提供一个minimal reproducible example。例如,粘贴您的文件示例包含您迄今为止尝试过的内容。
  • 使用edit 按钮将您的文件副本包含在您的问题中。然后显示提取的数据应该是什么样子。

标签: python csv text


【解决方案1】:

如果你的文件是这样的:

~hello
~this is an example
~i'm imagining what your file might be like
~i hope i'm right

那么这段代码应该可以工作:

file=open("info.txt", "r")
values=file.read().split("~")
values.pop(0)

【讨论】:

  • 这是一个txt文件,我对csv不太了解,但我认为你可以使用类似的方法
  • 我的文件将如下所示,其中包含换行符:--~--~--~--~--~--~--~--~--~-- ~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~xbchbshfbjdzbuygeyrgjdzhzuihewu45hriuy78646213wsdcvbgdreser bhbhgv hbhdbfhzdxf) _+)()*^ fddgfbduhygfdhxzxcvbnm lkjhg gggffd bgdd fds aqwe rtyi opp,./'; []=-0987654321 ?":{}|+_)(*&^%$#@!nhgdytsgfcusifu7fygtsygfyfrdfjhsd5e56 skjbftys sfkndytfdtwsy6 trd dgrdy 126;7';''',./';l[]]-=0 jhou8rdsj4nrzbwe4red sb resyf ASCVmnhgfstafdtg,./';[]=-0987654321?":{AASDFDFqeffrewrttg!@#$%^~--~--~--~
  • 如果你有一个 txt 文件,其中包含任意数量的新行,并且项目由 '~' 分隔,并且你想要一个列表,包括每个项目,新行表示为 \ n,不包括~,即使项目不是全部由新行分隔,上面的代码也应该可以工作。
【解决方案2】:

您可以将sep='~' 提供给pandas 的.read_csv() 方法(它将\n 解释为相应字段的一部分)。所以假设你的数据文件看起来像这样('blahs.csv'):

# contents of 'blahs.csv':
h0~h1~h2
blah00~blah01~blah02\n
blah10~blah11~blah12\n
blah20~blah21~blah22\n

然后你可以像这样导入 pandas 并读入:

import pandas as pd
blah = pd.read_csv('blahs.csv', sep='~')

blah
##     h0      h1        h2
## blah00  blah01  blah02\n
## blah10  blah11  blah12\n
## blah20  blah21  blah22\n

(顺便说一句,pandas 会像解释任何其他字符一样解释换行符,除非您另有说明。有关更多信息,请参阅official docs。)

【讨论】:

  • 我的文件看起来像这样,文本之间有换行符:--~--~--~--~--~--~--~--~--~-- ~--~--~--~--~--~--~--~--~--~--~--~--~--~--~--~xbchbshfbjdzbuygeyrgjdzhzuihewu45hriuy78646213wsdcvbgdreser bhbhgv hbhdbfhzdxf) _+)()*^ fddgfbduhygfdhxzxcvbnm lkjhg gggffd bgdd fds aqwe rtyi opp,./'; []=-0987654321 ?":{}|+_)(*&^%$#@!nhgdytsgfcusifu7fygtsygfyfrdfjhsd5e56 skjbftys sfkndytfdtwsy6 trd dgrdy 126;7';''',./';l[]]-=0 jhou8rdsj4nrzbwe4red sb resyf ASCVmnhgfstafdtg,./';[]=-0987654321?":{AASDFDFqeffrewrttg!@#$%^~--~--~--~
  • 在 "blah01" 之间,我有像 b\nla \n h01\n 这样的换行符,但 blah01 应该放在 csv 的单个单元格中
  • 是的,没关系——pd.read_csv() 仍会将其解析为一个单元格(至少在带有最新版本 pandas 的 python 36 中)。无论\n 出现在哪里,都可以按照描述工作。
【解决方案3】:

您的文件不是 CSV 文件。每个字段都有一个尾随分隔符。假设第一行是标题,这意味着您有 40 字段。要解析这个,您需要读取字符直到找到40 分隔符,然后在分隔符上拆分(然后跳过下一个换行符)。这可以使用生成器函数一次返回一行来完成,如下所示:

import re
import csv

delimiter = '~'

def get_row():
    with open('input.csv', 'r') as f_input:
        delimiter_count = 0
        skip_newline = False
        row_chars = []

        for c in f_input.read():
            if skip_newline:
                if c == '\n':
                    skip_newline = False
            elif c == delimiter:
                delimiter_count += 1

                if delimiter_count == 40:
                    yield ''.join(row_chars).split(delimiter)
                    row_chars = []
                    delimiter_count = 0
                    skip_newline = True
                else:
                    row_chars.append(c)
            else:
                row_chars.append(c)

        yield ''.join(row_chars).split(delimiter)

rows = [row for row in get_row()]
df = pd.DataFrame(rows[1:], columns=rows[0]).fillna('')
df.to_csv('output.csv', index=False)

生成的output.csv 包含正确以逗号分隔的单元格,其中包含用引号括起来的换行符的单元格。因此,它会正确加载到 Excel 中。

这也可以使用多行正则表达式来实现。

import re

with open('input.csv', 'r') as f_input:
    rows = re.findall('(([^\~]*\~){40}(\n|\Z))', f_input.read())
    rows = [row[0].rstrip('~\n').split('~') for row in rows]
    df = pd.DataFrame(rows[1:], columns=rows[0]).fillna('')
    df.to_csv('output.csv', index=False)

这虽然目前在您的文件上会失败,因为最后一行仅包含 29 分隔符。如果在末尾添加 11 个~ 字符,它会起作用。

【讨论】:

    猜你喜欢
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 2016-02-24
    • 1970-01-01
    相关资源
    最近更新 更多