【问题标题】:Build pandas dataframe with inconsistent data in each row构建每行数据不一致的 pandas 数据框
【发布时间】:2019-03-31 06:13:57
【问题描述】:

我正在尝试从一些数据构建多个数据帧,这些数据的内容(根据变量,而不是值)可能会在同一数据帧内的每一行中发生变化。

我现在尝试的方法是为每个新行构建一个新的 1 行数据框,然后使用 append 方法将其附加到现有数据框。这负责创建新列并将现有行的值设置为 NaN。

我还按照建议的here 尝试了loc 方法,但这会返回一个ValueError。

除此之外,我还可以拥有一千多个可能的标签。因此,我想避免必须在开头显式声明所有列,并且如果不读取整个文件至少一次,几乎不可能知道特定文件所需的所有列。

但是,我知道,逐行构建数据框被认为是一种不好的(如果不推荐使用的话)做法。

所以,假设我的数据来自一个与此类似的文本文件:

A=10,B=2
A=20,B=3
A=30,C=Batman

我想创建一个看起来像的数据框

    a    b       c
0  10  2.0     NaN
0  20  3.0     NaN
0  30  NaN  Batman

你建议怎么做?

编辑: 数据来自一个非常混乱的固定宽度文本。文本文件的每一行都是一个连续的字符序列(无分隔符)。行内有 3 个字母标识符,标记一个部分的开始,后面跟着该部分的值。我有一个文档,我翻译成一个 python 字典,它告诉我每个标识符在该部分开始之后我需要读取多少个字符以及它们是如何划分的。

例如。一行可能是

AAA1234BBB789aa78CCC123456

然后我会知道AAA 部分跟随 3 个值,一个由 2 位整数组成,两个由一位整数组成。该部分BBB 后跟一个 3 位整数、一个 2 字符字符串和 2 个一位整数。

我有一段代码可以把它翻译成一个看起来像这样的字典

{'AAA_1': 12, 'AAA_2':3, 'AAA_3':4, 'BBB_1':789, 'BBB_2':aa,'BBB_3':7, 'BBB_4':8, ......}

EDIT2:如果你想看看原始文件,你可以看这里(其中任何一个都可以):

ftp://ftp.ncdc.noaa.gov/pub/data/noaa/2017/

要了解如何阅读,请看这里(不想问你这么多):

ftp://ftp.ncdc.noaa.gov/pub/data/noaa/ish-format-document.pdf

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以将每一行作为一个字典,然后将它们组合成一个数据框

    dic1 = {'a':10,'b':2}
    dic2 = {'a':20,'b':3}
    dic3 = {'a':30,'c':'batman'}
    
    pd.DataFrame(data=[dic1,dic2,dic3])
    

    【讨论】:

    • 虽然简单,但最终成为最实用的解决方案,大约 75'000 行只需要 1-2 秒。
    【解决方案2】:

    看起来您的数据更适合存储为 JSON。 如果您可以将数据转换为 JSON,如下所示:

    data.json的内容:

    [
       {"A":10, "B":2},
       {"A":20, "B":3},
       {"A":30, "C":"Batman"}
    ]
    

    那么你可以简单地做:

    >>> df = pd.read_json('data.json')
    >>> print(df)
        A    B       C
    0  10  2.0     NaN
    1  20  3.0     NaN
    2  30  NaN  Batman
    

    【讨论】:

    • 数据来自一个非常混乱的固定宽度的 ASCII 文件。我认为没有现成的东西可以将它们转换为 JSON。我对 JSON 几乎一无所知,将数据从文本转换为 JSON,然后从 JSON 转换为 pandas 会比 Ashok KS 的回答更有效吗?你会建议走这条路吗?
    • 好吧,看起来您的数据几乎已经是 JSON 格式了。您需要做的就是:(1) 将 '=' 替换为 ':',(2) 在字符串周围加上引号,(3) 在每一行周围加上大括号,以及 (4) 在整个内容周围加上方括号。这有多容易取决于您的数据到底有多混乱......
    • 这不是我的数据格式。我用它来使它易于理解。我的数据类似于AAA1BBB123CCC123am。我需要知道每个部分的标识符(AAA,BBB,CCC 在这个例子中)有多少个字符跟随以及它们是如何划分的(例如,如果在 BBB 之后我有 123 或 1、2 和 3 或 12和 3 等)。为此,我有一个字典,但我希望之后将它们转换为熊猫。很抱歉这个误导性的例子,但我认为原始格式太复杂,与问题无关。
    • 在这种情况下,主要问题似乎是(有趣的)数据格式,因此它确实与问题非常相关。如果它不是标准格式,则不太可能有一段优雅的代码来阅读它。也许如果您提供更大的实际数据样本,我们可以再看看。
    【解决方案3】:

    假设数据以 csv 文件的形式出现。你可以阅读每一个像

    >>> print data1
         a       b    c
    0   10       2  5.0
    1    0     NaN  8.0
    2  NaN  batman  9.0
    3  cat     NaN  NaN
    
    >>> print data2
       a  b     d
    0  0  0   123
    1  0  0   fox
    2  0  0   883
    3  0  0  bats
    
    data1 = pd.read_csv('file1.csv',header=0)
    data2 = pd.read_csv('file2.csv'.header=0)
    

    然后:joined = pd.contact([data1,data2], sort=True).reset_index(drop=True)

    >>> print joined
         a       b    c     d
    0   10       2  5.0   NaN
    1    0     NaN  8.0   NaN
    2  NaN  batman  9.0   NaN
    3  cat     NaN  NaN   NaN
    4    0       0  NaN   123
    5    0       0  NaN   fox
    6    0       0  NaN   883
    7    0       0  NaN  bats
    

    【讨论】:

    • 很抱歉,原始数据不是 CSV。添加了更好的解释
    • 我从 pdf 和您已经编写的代码中看到,要将每一行转换为字典,您可以将单行作为一个数据帧读取,并且对于每个连续的行,重复创建数据帧并将它们连接到前一个。这可能是一种解决方案。
    • 这正是我现在正在做的事情。但是,正如文档中所写的那样,在 pandas 中进行连接是非常低效的。因此,我正在寻找替代方案。无论如何感谢您的想法
    猜你喜欢
    • 2015-08-13
    • 1970-01-01
    • 2019-10-22
    • 2016-05-31
    • 1970-01-01
    • 2016-08-05
    • 2021-03-25
    • 2018-12-09
    • 1970-01-01
    相关资源
    最近更新 更多