【问题标题】:Merging Pandas Dataframe from one CSV file with identical columns从具有相同列的一个 CSV 文件中合并 Pandas 数据框
【发布时间】:2017-10-04 16:13:26
【问题描述】:

我希望我的问题不是另一个问题的重复,但我已经搜索了三天,但还没有找到答案。

好的,我有一个包含两个标题的 CSV 文件。该文件包含有关酒店(他们的名称)、他们的成本(价格)、他们的评级以及他们的位置(区域 1、2 或 3)的信息:

The CSV file imported

如您所见,第一行描述了该区域,而第二行是酒店名称、价格和评级。我想要的是重新排列文件并将其保存到一个新的 CSV 文件中,格式如下所示:

The hopeful output

因此,有关酒店区域的信息已被赋予了自己的列。第二行的名字都是一样的。 有没有办法创建这个?当必须导入这些树状数据结构时,我有点陌生。如果树有更多节点(例如,如果我们从国家开始,向下移动到区域,然后向下移动到酒店名称、价格和评级),是否可以完成?可以用 Pandas 完成吗?

【问题讨论】:

  • 顺便说一句,我在这里完全是菜鸟,所以如果我做错了什么,请告诉我:)

标签: python-2.7 pandas csv


【解决方案1】:

首先,您可以将 csv 文件作为文本文件共享吗?这对尝试我自己的解决方案非常有帮助。把图片中的数据写下来似乎效率不高。

其次,您是否尝试过通过自己编写脚本来实现这一目标?或者你有没有试过使用一些图书馆?您添加了标签pandas,但在文本中您没有提及。它应该是熊猫有什么具体原因吗?

仅通过使用切片就可以轻松实现适用于该情况的解决方案。我猜你的格式是相当具体的而不是标准的,所以这些库可能没有多大帮助。熊猫允许多行作为标题,但以不同的方式解释,请参阅pandas dataframe with 2-rows header and export to csv

一个解决方案:

table = []
with open(my_csv_file) as f:
    for line in f:
        a1, p1, r1, a2, p2, r2, a3, p3, r3 = line[:-1].split(",")
        table.append([a1, p1, r1, "area1"])
        table.append([a2, p2, r2, "area2"])
        table.append([a3, p3, r3, "area3"])
# ... convert table into dataframe etc.

【讨论】:

  • 当然。有没有特定的方法可以在论坛上共享文件?否则我创建了一个链接:dropbox.com/s/5dpjt5p6p54799o/Hotels.csv?dl=0 它之所以需要 Pandas,是因为我已经制作了其他脚本,以便稍后进行一些其他类型的数据操作(对于问题并不重要,但只是为了澄清)。跨度>
  • 据我所知没有具体的方法,但最好的方法是您可以只查看和复制文本而无需下载可能含有病毒的文件的地方,例如github gist 或 pastebin 或类似的东西。
  • 现在我用您的数据检查了我的解决方案并且它有效。只需将open(my_csv_file) 替换为with io.StringIO("""Area1;;;Area 2;;;Area 3;; Hotel;Price ;Rating;Hotel;Price ;Rating;Hotel;Price ;Rating A;200;1;D;350;3;G;500;1 B;500;4;E;400;2;H;200;3 C;300;5;F;500;5;I;700;5 """) as f: 即可。当然,这可以概括。如果你这样做,也许可以使用 github gist 并在这里分享:)
  • 解决方案能否再概括一点?例如,如果有 N 个不同的区域和 20 个不同的值来描述酒店(名称除外)怎么办?您的解决方案可以更加动态吗?谢谢您的帮助。如果文件有一个额外的标题描述国家(例如,假设德国,然后有区域 1 和区域 2(以及随后的酒店名称列表以及相应的价格和评级),以及法国,它有区域 3,区域 4和区域 5)。解决方案可以推广到这个吗?
  • 好吧,我认为解决您的问题不是我的任务。对我来说,stackoverflow 是关于提供其他提示他们如何自己解决问题。或指出需要更改以使其最终起作用的一行。所以请你自己想出一个概括的尝试,如果你在某个部分遇到困难,我会帮你解决那个部分。但我不会做你的功课。
【解决方案2】:

好的,所以我为这个问题创建了一个可能的解决方案:

infile = csv.reader(infile, delimiter=';')
    out = []
    counter = 0
    i = 0
    k = 0
    names = []
    temp1 = 0
    for line in infile:
        temp = list(set(line))
        if counter == 0:
            names = line
            counter +=1
        elif counter == 1:
            k = len(list(set(line)))
            while i < len(line):
                line.insert(i+k, name)
                i += (k + 1)
            counter += 1
            out.append(line)
        else:
            i = 0
            ind = 0
            while i < len(line):
                line.insert(i+k, names[ind*k])
                i += (k + 1)
                ind +=1
            out.append(line)
    headers = out.pop(0)
    n = len(set(headers))
    table = pd.DataFrame(out, columns=headers)
    for i in range(0, len(table.columns)):
        if i ==0:
            temp1 = table.ix[:,n*i:n*(i+1)]
        else:
            temp1 = pd.concat([temp1, table.ix[:,n*i:n*(i+1)]], ignore_index=True)

我非常想要一些输入和建议,以使解决方案更优雅或向文件添加额外级别的标题。

【讨论】:

  • 整个代码没有很好的分离。你有没有想过把它分成几个功能,一个用于读取标题,一个用于读取正文?像temp = list(set(line)) 这样的许多行看起来很老套,而 cmets 会很好。您使用的变量名称很少解释它们的用途。你能想出更好的名字吗?并且我建议使用库unittest来检查代码是否在不同的条件下运行。
  • 感谢 Mkastner 的输入。我将它分开更多,以便更容易分析。我还将重命名变量以便于理解:)
猜你喜欢
  • 2020-12-10
  • 2015-03-21
  • 2021-03-06
  • 2017-06-24
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 2017-05-18
  • 1970-01-01
相关资源
最近更新 更多