首页 > 解决方案 > Python。获取每列沿行的不间断段长度

问题描述

我有一个像这样的文件,分段为 0、1 和 2:

0000000001111100110002220000000011111111
0011100000111000000220111110001111100000
1110011111111111000001111000002222111000
0011110001110000000220220000001111100000

例如,第 1 行有 9 个 0 的段,然后是 5 个 1 的段,然后是 2 个 0 的段,依此类推。在这个玩具示例中,每一行从位置 0 到 39(Python),但实际上它从 0 到 >2000000 并且有 >10000 行。对于每一列,我想获得 0、1 和 2 的不间断段的长度。例如,对于:

column 0, level 0, I have: 9, 2, 0 and 2. 
column 0, level 1, I have: 0, 0, 3 and 0. 
column 0, level 2, I have: 0, 0, 0 and 0. 

For column 10, level 0: 0,5,0 and 0
For column 10, level 1: 5,0,11 and 3
For column 10, level 2: 0,0,0 and 0

For column 23, level 0: 0,0,0 and 0
For column 23, level 1: 0,5,4 and 0
For column 23, level 2: 3,0,0 and 2

最后,我希望有 3 个不同的矩阵(用于级别 0、1 和 2)以及每列的段长度。

对于 0,它看起来像这样:

9.........0............0.................
2.........0............0.................
0.........0............0.................
2.........0............0.................

对于 1:

0.........5............0.................
0.........3............0.................
3.........11............0.................
0.........3............0.................

对于 2:

0.........0............3.................
0.........0............0.................
2.........0............0.................
0.........0............2.................

如何用 Python numpy 或 pandas 做到这一点?

标签: pythonmatrix

解决方案


假设您可以将文件读入字符串列表(例如使用 readlines),您可以使用 itertools.groupby 创建 (level, count) 元组的数据框,然后遍历这些数据框以获得所需的结果,这里是:

import itertools
import pandas as pd
import numpy as np

l = \
["0000000001111100110002220000000011111111",
"0011100000111000000220111110001111100000",
"1110011111111111000001111000002222111000",
"0011110001110000000220220000001111100000"]

def level_and_count(row):
    g1 = [(x[0], len(list(x[1]))) for x in itertools.groupby(row)]
    return sum([[x]*x[1] for x in g1], [])

df = pd.DataFrame([level_and_count(row) for row in l])

def mat_by_level(df, level):
    aa = df.apply(lambda c: [x[1] if x[0]==level else 0 for x in c],   axis=1)
    return pd.DataFrame(np.vstack(aa))

现在,当我们拥有这些函数时,我们可以在每个级别上运行它们并将结果保存到一个文件中(在此示例中以逗号分隔):

for level in ['0', '1', '2']:
    mat_by_level(df, level).to_csv(f'level_{level}.csv', index=False, header=False) 

让我知道这是否是您的意思。


推荐阅读