将 txt 文件解析为数据框,根据多个分隔符填充列

Parsing a txt file into data frame, filling columns based on the multiple separators

有一个 .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)

gives the following result

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

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

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

使用

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

It became this

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

我认为你最好自己解析文件,而不是依赖 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'}}

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

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

数据:

lines = [
"a 1:0.0002 3:0.0003",
"b 2:0.0002 3:0.0003",
"a 1:0.0002 2:0.0003"]
l = pd.Series(lines)
type_ = l.apply(lambda x:x.split()[0]).to_list()
df = (pd.DataFrame(
    l.apply(lambda x:{i.split(":")[0] : i.split(":")[1] for i in x.split()[1:]}).to_dict()
).T).assign(type_=type_).iloc[:, [3,0,1,2]]

df:

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