【问题标题】:Data Manipulation using Python使用 Python 进行数据操作
【发布时间】:2018-08-10 15:06:44
【问题描述】:

我有一个需要使用 Python 解析的非结构化文件。在检索文件时执行一些初始操作后,数据采用以下格式(标题只是虚拟的,它们可以是任何东西,例如 INDEX LENGTH、WIDTH 等)

data = [
    [" title1-a", "title2-a", "title3-a", " title4-a"], 
    ["title1-b ", " title2-b", "title3-b ", "title4-b"], 
    ["title3-c", " title4-c  "],
    ["title1-a ", "  title5-a"],
    ["title1-b", " title5-b"],
    ["title5-c "]
]

以上数据为假数据。真实数据集如下所示

real = [
    ['TIME', 'YEARS', 'WWPR', 'WWPR', 'WWPR', 'WWPR', 'WOPR', 'WOPR', 'WOPR', 'WOPR'],
    ['DAYS', 'YEARS', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY'],
    ['P1', 'P2', 'P3', 'P4', 'P1', 'P2', 'P3', 'P4'],
    ['TIME', 'WWIR'],
    ['DAYS', 'STB/DAY'],
    ['I1']
]

注意,每个标题是三个列表的串联!所以,

real = [[
    ['TIME', 'YEARS', 'WWPR', 'WWPR', 'WWPR', 'WWPR', 'WOPR', 'WOPR', 'WOPR', 'WOPR'],
    ['DAYS', 'YEARS', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY'],
    ['P1', 'P2', 'P3', 'P4', 'P1', 'P2', 'P3', 'P4']],[
    ['TIME', 'WWIR'],
    ['DAYS', 'STB/DAY'],
    ['I1']
]]

解析真实数据,实现如下字符串

TIME DAYS
YEARS YEARS
WWPR STB/DAY P1
WWPR STB/DAY P2
WWPR STB/DAY P3
WWPR STB/DAY P4
WOPR STB/DAY P1
WOPR STB/DAY P2
WOPR STB/DAY P3
WOPR STB/DAY P4
WWIR STB/DAY I1

目标如下

  1. 连接相关的标题条目;
  2. 必须保留标题的顺序;
  3. 不允许重复;
  4. 尽可能减少复制操作;

根据虚拟数据,所需的输出如下所示

output = [
    "title1-a title1-b", 
    "title2-a title2-b",
    "title3-a title3-b title3-c",
    "title4-a title4-b title4-c",
    "title5-a title5-b title5-c"
]

我已经开发了一个解决方案。这就是说,必须有一种更清洁、更有效的方法。因此,我热衷于研究替代解决方案。以下是我为将上述数据转换为所需输出格式而开发的代码。

def _getTitleData(title_data):
    seen = set()
    titleRows = 3

    # bundle title row(s)
    titles = [
                 title_data[index:index + titleRows] 
                 for index in range(0, len(title_data), titleRows)
             ]

    # apply padding to simplify concatination
    for title in titles:
        firstRow = title[0]
        lastRow = title[len(title) - 1]

        lengthFirstRow = len(firstRow)
        lengthLastRow = len(lastRow)

        if(lengthFirstRow > lengthLastRow):
            for index in range(lengthFirstRow - lengthLastRow):
                lastRow.insert(0, '')

    # strip and concatinate titles
    titles = [
                 ' '.join(word).strip() 
                 for title in titles 
                 for word in zip(*title)
             ]

    # remove duplicate entries
    titles = [
                 title 
                 for title in titles 
                 if not (title in seen or seen.add(title))
             ]

    [print(title) for title in titles]
    return titles

【问题讨论】:

  • :s 上面真的没有其他合适的“pythonic”解决方案吗?

标签: python data-manipulation


【解决方案1】:

请看一下我的建议:

data = [
    [" title1-a", "title2-a", "title3-a", " title4-a"], 
    ["title1-b ", " title2-b", "title3-b ", "title4-b"], 
    ["title3-c", " title4-c  "],
    ["title1-a ", "  title5-a"],
    ["title1-b", " title5-b"],
    ["title5-c "]
]

unique = set()

for i in data:
    for j in i:
        unique.add(j.strip(" ") )

print(sorted(list(unique)))

【讨论】:

  • 稍微修改您的代码以提供 OP 所需的输出,其中每行的标题串联。顺便说一句,您的代码运行良好。
  • 哎呀,我刚刚意识到我错过了连接部分
  • 优秀的解决方案。我会投票赞成。这就是说,我不能使用sorted,因为原始帖子中的标题只是假人。这些标题只是为了展示概念。不过,我需要确保保留标题的顺序。
【解决方案2】:

根据您提供的真实数据,这是我想出的解决方案:

real = [[
    ['TIME', 'YEARS', 'WWPR', 'WWPR', 'WWPR', 'WWPR', 'WOPR', 'WOPR', 'WOPR', 'WOPR'],
    ['DAYS', 'YEARS', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY', 'STB/DAY'],
    ['P1', 'P2', 'P3', 'P4', 'P1', 'P2', 'P3', 'P4']],[
    ['TIME', 'WWIR'],
    ['DAYS', 'STB/DAY'],
    ['I1']
]]

maxLists = 3
numOfSublists = len(real)
lengths = [len(elem[0]) for elem in real]
for i in range(numOfSublists):
    real[i][2] = [' '] * (lengths[i]-len(real[i][2])) + real[i][2]

dups = set()
output = [" ".join(j) for i in range(numOfSublists) for j in list(zip(*real[i])) if not (" ".join(j) in dups or dups.add(" ".join(j)))]
for i in output:
    print(i)

输出:

TIME DAYS  
YEARS YEARS  
WWPR STB/DAY P1
WWPR STB/DAY P2
WWPR STB/DAY P3
WWPR STB/DAY P4
WOPR STB/DAY P1
WOPR STB/DAY P2
WOPR STB/DAY P3
WOPR STB/DAY P4
WWIR STB/DAY I1

【讨论】:

  • 也是一个很好的解决方案。这就是说,我不能使用sorted。虚拟数据中的标题仅供展示。真正的标题可以是任何东西,例如长度、宽度、成本等。也就是说,我确实需要确保保留订单。
  • 感谢您的反馈。我会编辑我的答案,但会更长一些。
  • 非常感谢。 Python 不是我通常使用的语言。我已经可以看到对我当前代码的巨大改进。非常感谢您的时间
  • 我已经添加了真实案例。我解析的数据,以及它被解析的结果。我希望这些修改能让目标更加明确。
猜你喜欢
  • 2017-12-18
  • 2014-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 2019-10-18
  • 2018-05-04
相关资源
最近更新 更多