【问题标题】:Extract data from list using a delimiter使用分隔符从列表中提取数据
【发布时间】:2019-08-06 12:48:59
【问题描述】:

我有一组 10 个 Python 列表,格式如下:

[ABC*DEF*123>~123*999*HHH]
[PQR*RST*567>~AWS*999*POI]
[XYZ*TGT*234>~2352*245*HFT]
[STU*DEF*789>~654*345*QQQ]

我正在尝试从上面的列表中提取数据,以便最终输出是 Dataframe 并且期望以下输出

123,999,HHH
AWS,999,POI
2352,245,HFT
654,345,QQQ

以下是我迄今为止所做的:

allFiles = Path where all the txt files are stored
list_ = []
for file_ in allFiles:
    with open(file_) as fp:
        lines1 = fp.read().split('\n')
        b = [i.split('~', 1)[1] for i in lines1]
        print(b)

上面给了我一个如下列表:

[123*999*HHH]
[AWS*999*POI]
[2352*245*HFT]
[654*345*QQQ]

我无法使用分隔符 (*) 提取上述数据并将它们分成不同的列并将其保存到数据框

【问题讨论】:

    标签: python string pandas list


    【解决方案1】:

    您可以首先创建一个以字符串列表为行的数据框,然后使用str.split 将每个字符串拆分为~。然后,您可以只选择第二个术语然后再拆分结果,这次是*,设置expand=True

    l1 = ['ABC*DEF*123>~123*999*HHH']
    l2 = ['PQR*RST*567>~AWS*999*POI']
    l3 = ['XYZ*TGT*234>~2352*245*HFT']
    l4 = ['STU*DEF*789>~654*345*QQQ']
    
    df = pd.DataFrame([l1,l2,l3,l4], columns=['col1'])
    df.col1.str.split('~').str[1].str.split('*', expand=True)
    
         0    1    2
    0   123  999  HHH
    1   AWS  999  POI
    2  2352  245  HFT
    3   654  345  QQQ
    

    更新

    对于来自多个文件的列表执行上述操作:

    l = []
    for file_ in allFiles:
        f = open(file_, 'r')
        l.extend([line.rstrip('\n') for line in f.readlines()])
    

    然后和之前一样:

    df = pd.DataFrame(l, columns=['col1'])
    df.col1.str.split('~').str[1].str.split('*', expand=True)
    

    【讨论】:

    • 感谢回复,但列表数量不固定。它动态变化。我怎么能有上面的工作,这样我们就不必定义列表的数量了。谢谢。
    • @scottmartin 您的列表是如何保存的?在更大的列表中?
    • 我读取的每个文件都存储为一个列表。如我最初的帖子所示,由于我从文件夹中读取文件(其中 n 是文件夹中的文件数),我有“n”个列表。希望我在这里回答了你的问题。
    【解决方案2】:

    使用read_csv 和分隔符~ 和参数names,然后为DataFrame 的第二列添加Series.str.split

    import pandas as pd
    
    temp=u"""ABC*DEF*123>~123*999*HHH
    PQR*RST*567>~AWS*999*POI
    XYZ*TGT*234>~2352*245*HFT
    STU*DEF*789>~654*345*QQQ"""
    #after testing replace 'pd.compat.StringIO(temp)' to 'filename.csv'
    df = pd.read_csv(pd.compat.StringIO(temp), sep="~", names=['a','b'])
    
    df = df['b'].str.split('*', expand=True)
    print (df)
          0    1    2
    0   123  999  HHH
    1   AWS  999  POI
    2  2352  245  HFT
    3   654  345  QQQ
    

    如果想使用您的解决方案,请添加另一个split

    list_ = []
    for file_ in allFiles:
    with open(file_) as fp:
        lines1 = fp.read().split('\n')
        b = [i.split('~', 1)[1].split('*') for i in lines1]
        list_.append(b)
    
    df = pd.DataFrame([y for x in list_ for y in x])
    print(df)
    

    【讨论】:

    • 谢谢。我添加了另一行,在其中将列表保存到 Dataframe,只看到最后一个列表/文件被保存。 df = pd.DataFrame(b) 请您帮忙。谢谢。
    • @scottmartin - 你现在能检查一下吗?
    • 只是另一个帮助。在执行上述拆分后,我有几行具有诸如 0001~ABC 之类的值。您能否建议我如何修改上面的代码,以便我可以在您上面共享的最新更新代码上应用这个额外的 split('~') 方法..
    • @scottmartin - 更好的是创建新问题。
    【解决方案3】:

    既然你已经有了列表,一个简单的函数可以在分隔符(*)上拆分。

    l1 = ["123*999*HHH"]
    l2 = ["AWS*999*POI"]
    l3 = ["2352*245*HFT"]
    l4 = ["654*345*QQQ"]
    
    def split_delim(l):
        for i in l:
            l = i.split('*')
        return l
    
    l1 = split_delim(l1)
    l2 = split_delim(l2)
    l3 = split_delim(l3)
    df = pd.DataFrame({'l1':l1, 'l2':l2, 'l3':l3})
    df
        l1      l2      l3
    0   123     AWS     2352
    1   999     999     245
    2   HHH     POI     HFT
    

    独立于列表数量的更通用的解决方案。这会在形成数据帧之前执行所有拆分操作。

    #allFiles = Path where all the txt files are stored
    
    def split_delim(Files):  
        list_ = []
        for file_ in Files:
            with open(file_) as fp:
                lines1 = fp.read().split('\n')
                b = [i.split('~', 1)[1] for i in lines1]
                for i in b:
                    l = i.split('*')
                    list_.append(l)                
        return list_
    
    list_new = split_delim(allFiles)
    
    df = pd.DataFrame(list_new, columns=['col1'])
    

    【讨论】:

      【解决方案4】:

      您必须明确指定分隔符,例如

      print('ABC*DEF*123>~123*999*HHH'.split('~')[1].split('*'))
      

      产生:

      ['123', '999', 'HHH']
      

      【讨论】:

        猜你喜欢
        • 2021-08-21
        • 2016-05-21
        • 2012-08-19
        • 2019-10-01
        • 1970-01-01
        • 2013-08-12
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多