【问题标题】:Creating pandas dataframe from list of dictionaries containing lists of data从包含数据列表的字典列表创建熊猫数据框
【发布时间】:2014-11-20 05:43:51
【问题描述】:

我有一个具有这种结构的字典列表。

    {
        'data' : [[year1, value1], [year2, value2], ... m entries],
        'description' : string,
        'end' : string,
        'f' : string,
        'lastHistoricalperiod' : string, 
        'name' : string,
        'series_id' : string,
        'start' : int,
        'units' : string,
        'unitsshort' : string,
        'updated' : string
    }

我想把它放在一个看起来像这样的 pandas DataFrame 中

   year       value  updated                   (other dict keys ... )
0  2040  120.592468  2014-05-23T12:06:16-0400  other key-values
1  2039  120.189987  2014-05-23T12:06:16-0400  ...
2  other year-value pairs ...
...
n

其中 n = m* len(list with dictionaries)(其中“数据”中每个列表的长度 = m)

也就是说,'data' 中的每个元组都应该有自己的行。到目前为止我所做的是:

x = [list of dictionaries as described above]
# Create Empty Data Frame
output = pd.DataFrame()

    # Loop through each dictionary in the list
    for dictionary in x:
        # Create a new DataFrame from the 2-D list alone.
        data = dictionary['data']
        y = pd.DataFrame(data, columns = ['year', 'value'])
        # Loop through all the other dictionary key-value pairs and fill in values
        for key in dictionary:
            if key != 'data':
                y[key] = dictionary[key]
        # Concatenate most recent output with the dframe from this dictionary.
        output = pd.concat([output_frame, y], ignore_index = True)

这看起来很hacky,我想知道是否有更“pythonic”的方式来做到这一点,或者至少这里是否有任何明显的加速。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    如果您的数据格式为[{},{},...],您可以执行以下操作...

    您的数据的问题在于您的字典的数据键。

    df = pd.DataFrame(data)
    fix = df.groupby(level=0)['data'].apply(lambda x:pd.DataFrame(x.iloc[0],columns = ['Year','Value']))
    fix = fix.reset_index(level=1,drop=True)
    df = pd.merge(fix,df.drop(['data'],1),how='inner',left_index=True,right_index=True)
    

    代码执行以下操作...

    1. 使用您的字典列表创建一个 DataFrame
    2. 通过将数据列扩展到更多行来创建新数据框
    3. 拉伸线导致多索引与不相关的列 - 这将其删除
    4. 最后在原索引上合并,得到想要的DataFrame

    【讨论】:

    • 我非常喜欢这个解决方案。由于一切都始于数据帧,因此几乎没有机会修改代码以将每个“数据”列表与其他标题信息解耦。
    【解决方案2】:

    在回答这个问题时,一些数据会很有帮助。但是,从您的数据结构来看,一些示例数据可能如下所示:

    dict_list = [{'data'            : [['1999', 1], ['2000', 2], ['2001', 3]],
                  'description'     : 'foo_dictionary',
                  'end'             : 'foo1',
                  'f'               : 'foo2',},
                 {'data'            : [['2002', 4], ['2003', 5]],
                  'description'     : 'bar_dictionary',
                  'end'             : 'bar1',
                  'f'               : 'bar2',}
                 ]
    

    我的建议是将这些数据操作并重塑为一个新字典,然后将该字典简单地传递给 DataFrame 构造函数。为了将字典传递给pd.DataFrame 构造函数,您可以非常简单地将数据重塑为新的字典,如下所示:

    data_dict = {'years'        : [],
                 'value'        : [],
                 'description'  : [],
                 'end'          : [],
                 'f'            : [],}
    
    for dictionary in dict_list:
        data_dict['years'].extend([elem[0] for elem in dictionary['data']])
        data_dict['value'].extend([elem[1] for elem in dictionary['data']])
        data_dict['description'].extend(dictionary['description'] for x in xrange(len(dictionary['data'])))
        data_dict['end'].extend(dictionary['end'] for x in xrange(len(dictionary['data'])))
        data_dict['f'].extend(dictionary['f'] for x in xrange(len(dictionary['data'])))
    

    然后将其传递给 pandas

    import pandas as pd
    pd.DataFrame(data_dict)
    

    这给了我以下输出:

          description   end     f  value years
    0  foo_dictionary  foo1  foo2      1  1999
    1  foo_dictionary  foo1  foo2      2  2000
    2  foo_dictionary  foo1  foo2      3  2001
    3  bar_dictionary  bar1  bar2      4  2002
    4  bar_dictionary  bar1  bar2      5  2003
    

    我想说,如果这是您想要的输出类型,那么这个系统将是一个不错的简化。

    实际上,您可以通过创建 year:value 字典和其他 val 的 dict 来进一步简化它。这样您就不必输入新字典,并且可以运行嵌套的 for 循环。这可能如下所示:

    year_val_dict = {'years'        : [],
                     'value'        : []}
    other_val_dict = {_key : [] for _key in dict_list[0] if _key!='data'}
    
    for dictionary in dict_list:
        year_val_dict['years'].extend([elem[0] for elem in dictionary['data']])
        year_val_dict['value'].extend([elem[1] for elem in dictionary['data']])
        for _key in other_val_dict:
            other_val_dict[_key].extend(dictionary[_key] for x in xrange(len(dictionary['data'])))
    
    year_val_dict.update(other_val_dict)
    pd.DataFrame(year_val_dict)
    

    注意,这当然假设 dict_list 中的所有 dicts 具有相同的结构....

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      相关资源
      最近更新 更多