首页 > 解决方案 > 将txt文件解析为数据框,根据多个分隔符填充列

问题描述

有一个 .txt 文件

结构如下

#n  1
a 1:0.0002 3:0.0003...
#n  2
b 2:0.0002 3:0.0003...
#n  3
a 1:0.0002 2:0.0003... 
...

试图解析成以下结构的数据框

#    type  1        2       3 
1    a     0.0002   null    0.0003 ....
2    b     null     0.0002  0.0003 ....
3    a     0.0002   0.0003  null   ....
...

描述规则:

# i - 'i' 是行号
n:data - 'n' 是要填充的列号,'data' 是要填充到第 i 行的值

如果列数足够小,则可以手动完成,但考虑的 txt 大约有 2000-3000 个列值,其中一些列值丢失。

import pandas as pd
data = pd.read_csv("filename.txt", sep = "#", header = None)

给出以下结果

data1 = data.iloc[1::2]
data2 = data.iloc[::2]

我试图删除 data1 中的奇数行,甚至在 data2 中,然后希望弄清楚如何拆分奇数并合并 2 个 df,但可能有一种更快、更漂亮的方法来做到这一点,这就是为什么在这里问

更新,花了 3 个小时弄清楚如何使用数据框,因为我对它们不太熟悉。现在 从那

使用

import pandas as pd
df = pd.read_csv("myfile.txt", sep = "#", header = None)
for index, col in df.iterrows():
    if index%2 == 0:
        col[1] = int(col[1].split('\t')[1])
for index, col in df.iterrows():
    if index%2 == 1:
#         print(col[0])
        col[0] = col[0].split(' ')
df[0] = df[0].shift(-1)
df = df.iloc[::2]
df = df[[1,0]]
df = df.rename(columns={0: 1, 1: 0})
df.index = range(len(df))

变成了这个

关于如何添加未知数量的幻像列并使用列表中的“n:value”填充它们以用“value”填充“n”列的任何建议?

标签: pythonpandasdataframeseparatortxt

解决方案


我认为您最好自己解析文件,而不是依赖read_csv然后处理混乱。这是我将如何做到的。由于我无权访问您的真实文件,因此我在您的问题中使用了一个小示例。首先,加载文件。

from io import StringIO
file = StringIO(
"""\
#n  1
a 1:0.0002 3:0.0003
#n  2
b 2:0.0002 3:0.0003
#n  3
a 1:0.0002 2:0.0003
""")
# You would just use file = open('myfile.txt','r) instead of the above

然后我们读取所有行,将它们成对分组,解析并将结果粘贴到字典中

# read all lines
lines = file.readlines()

# here we will store the results, dictionary of dictionaries
parsing_res = {}

# a fancy way of processing two lines, odd and even, at the same time
for line1,line2 in zip(lines[::2],lines[1::2]):
    # line1 has the form '#n  1', we split on whitespace and take the second tokem
    row_index = line1.split()[1]
    # line2 is the other type of lines, split into tokens by whitespace
    tokens = line2.split()
    # first one is 'type'
    t = tokens[0]

    # the others are pairs 'x:y', split them into x,y and stick into a dictionary with label x and value y
    row_dict = {token.split(':')[0]:token.split(':')[1] for token in tokens[1:]}

    # add type
    row_dict['type'] = t
   
    # store the result for these two lines into the main dictionary
    parsing_res[row_index] = row_dict
parsing_res

现在我们有一些看起来像这样的东西:

{'1': {'1': '0.0002', '3': '0.0003', 'type': 'a'},
 '2': {'2': '0.0002', '3': '0.0003', 'type': 'b'},
 '3': {'1': '0.0002', '2': '0.0003', 'type': 'a'}}

这个 dict 现在可以直接用于创建一个数据框,我们继续这样做并且还对列进行排序,因为它们的顺序有点随机

df = pd.DataFrame.from_dict(parsing_res, orient='index')
df.reindex(sorted(df.columns), axis=1).reindex(sorted(df.index), axis=0)

输出

    1       2       3       type
1   0.0002  NaN     0.0003  a
2   NaN     0.0002  0.0003  b
3   0.0002  0.0003  NaN     a

推荐阅读