使用定界符从列表中提取数据

时间:2019-03-15 12:27:04

标签: python string pandas list

我有一组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]

我正在尝试从上面的列表中提取数据,以使最终输出为数据框并期望以下输出

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]

我无法使用定界符(*)提取上述数据并将其拆分为不同的列,并将其保存到数据框

4 个答案:

答案 0 :(得分:5)

您可以首先创建一个以字符串列表为行的数据框,然后使用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)

答案 1 :(得分:1)

由于已经有了列表,因此可以在定界符(*)上拆分一个简单的函数。

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'])

答案 2 :(得分:1)

read_csv与分隔符~和参数name一起使用,然后为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)

答案 3 :(得分:0)

例如,您必须明确指定定界符

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

产生:

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