【问题标题】:Merge line with previous if new line starts with "|" pipe in dataframe如果新行以“|”开头,则将行与上一行合并数据框中的管道
【发布时间】:2020-01-15 16:52:20
【问题描述】:

考虑以下文本场景:

df = pd.read_csv('dummy.txt', sep='|')
        ID   Name           Email Country  Quantity
0  2.0  name2  name@email.com      UK       8.0
1  3.0  name3  name@email.com     NaN       NaN
2  NaN     UK               8     NaN       NaN
3  5.0  name4  name@email.com     NaN       NaN
4  NaN     UK               8     NaN       NaN
5  7.0  name5  name@email.com      UK       8.0

原始数据为:

ID|Name|Email|Country|Quantity
2|name2|name@email.com|UK|8
3|name3|name@email.com
|UK|8
5|name4|name@email.com
|UK|8
7|name5|name@email.com|UK|8

所以有一个带有“|”的虚线。逻辑应该是:如果行以“|”开头然后与它所属的上一行合并

结果应该是:

ID|Name|Email|Country|Quantity
2|name2|name@email.com|UK|8
3|name3|name@email.com|UK|8
5|name4|name@email.com|UK|8
7|name5|name@email.com|UK|8

Linux 代码完成这项工作:

sed -z 's/\n|/|/g

但是,我无法在 Python 中执行此操作。

【问题讨论】:

    标签: python csv dataframe row


    【解决方案1】:

    使用re模块(regex101):

    txt = '''ID|Name|Email|Country|Quantity
    2|name2|name@email.com|UK|8
    3|name3|name@email.com
    |UK|8
    5|name4|name@email.com
    |UK|8
    7|name5|name@email.com|UK|8'''
    
    import re
    
    txt = re.sub(r'\n\|', '|', txt)
    print(txt)
    

    打印:

    ID|Name|Email|Country|Quantity
    2|name2|name@email.com|UK|8
    3|name3|name@email.com|UK|8
    5|name4|name@email.com|UK|8
    7|name5|name@email.com|UK|8
    

    加载为 pandas DataFrame:

    df = pd.read_csv(StringIO(txt), sep='|')
    print(df)
    

    打印:

       ID   Name           Email Country  Quantity
    0   2  name2  name@email.com      UK         8
    1   3  name3  name@email.com      UK         8
    2   5  name4  name@email.com      UK         8
    3   7  name5  name@email.com      UK         8
    

    编辑:要从文件中读取,您可以使用:

    import re
    import sys
    import pandas as pd
    
    if sys.version_info[0] == 2:  # Not named on 2.6
        from StringIO import StringIO
    else:
        from io import StringIO
    
    with open('dummy.txt', 'r') as f_in:
        txt = f_in.read()
    
    txt = re.sub(r'\n\|', '|', txt)
    
    df = pd.read_csv(StringIO(txt), sep='|')
    
    print(df)  # or 'print df' in Python2
    

    打印:

       ID   Name           Email Country  Quantity
    0   2  name2  name@email.com      UK         8
    1   3  name3  name@email.com      UK         8
    2   5  name4  name@email.com      UK         8
    3   7  name5  name@email.com      UK         8
    

    【讨论】:

    • 谢谢!我实际上是从 Athena 查询数据,并且数据已经作为数据框返回。当我应用这个正则表达式时,返回以下错误:ypeError: expected string or bytes-like object.
    • @Sama 所以损坏的字符串在某个列/单元格中?如果是,您需要先访问它,然后再将其提供给re.sub
    • 我认为我可以在分配 add 'Nan' 值时访问它。上述数据是虚拟数据,但逻辑和问题是相同的。您的解决方案是针对原始数据,然后将其放入数据框中。
    • @Sama 我想我不太明白,你能编辑你的问题并将数据框放在那里吗?所以我可以看到它......
    • 考虑到上述变化,该解决方案不适用于数据帧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 2016-11-05
    • 2018-05-07
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    相关资源
    最近更新 更多