【问题标题】:How to convert nested dictionary to dataframe?如何将嵌套字典转换为数据框?
【发布时间】:2017-09-04 11:06:27
【问题描述】:

我有一个嵌套字典。这是纳斯达克的一些数据。像这样:

{'CLSN':     
 Date        Open  High   Low  Close  Volume  Adj Close                                                
 2015-12-31  1.92  1.99  1.87   1.92   79600       1.92
 2016-01-04  1.93  1.99  1.87   1.93   39700       1.93
 2016-01-05  1.89  1.94  1.85   1.90   50200       1.90,
 'CCC':    
 Date            Open       High        Low      Close  Volume  Adj Close                                                              
 2015-12-31  17.270000  17.389999  17.120001  17.250000  177200  16.965361
 2016-01-04  17.000000  17.219999  16.600000  17.180000  371600  16.896516
 2016-01-05  17.190001  17.530001  17.059999  17.450001  417500  17.162061,
}

为了帮助您理解,它是 key 后跟 values,而 values 是一个 dataframe

在问之前,我尝试了pd.Panel(nas)['CLSN']的方式,所以我确定它的值是一个数据框。但是pd.Panel(nas).to_frame().reset_index()的方式对我一点帮助都没有!它输出一个包含数千列的空数据框,这些列由股票名称填充。

现在很麻烦,我想要一个这样的数据框:

index  Date      Open       High       Low       Close      Volume     Adj Close                                            CLSN 2015-12-31  1.92       1.99       1.87       1.92       79600.0   1.92
CLSN 2016-01-01   NaN       NaN        NaN        NaN        NaN       NaN
ClSN 2016-01-04  1.93       1.99       1.87       1.93       39700.0   1.93  
CCC  2015-12-31  17.270000  17.389999  17.120001  17.250000  177200.0  16.965361
CCC  2016-01-04  17.000000  17.219999  16.600000  17.180000  371600.0  16.896516
CCC  2016-01-05  17.190001  17.530001  17.059999  17.450001  417500.0  17.162061

当然,我可以使用for 循环来获取每只股票的数据框,但加入它们会杀了我。

你有更好的主意吗?非常愿意知道!


到 MaxU: 使用print(nas['CLSN'].head())方法后,输出如下:

            Open  High   Low  Close  Volume  Adj Close
Date                                                  
2015-12-31  1.92  1.99  1.87   1.92   79600       1.92
2016-01-04  1.93  1.99  1.87   1.93   39700       1.93
2016-01-05  1.89  1.94  1.85   1.90   50200       1.90
2016-01-06  1.86  1.89  1.77   1.78   62100       1.78
2016-01-07  1.75  1.80  1.75   1.77  117000       1.77

【问题讨论】:

    标签: python pandas dictionary dataframe


    【解决方案1】:

    更新:

    假设Date 是一个索引(不是常规列):

    源字典:

    In [70]: d2
    Out[70]:
    {'CCC':                  Open       High        Low      Close  Volume  Adj Close
     Date
     2015-12-31  17.270000  17.389999  17.120001  17.250000  177200  16.965361
     2016-01-04  17.000000  17.219999  16.600000  17.180000  371600  16.896516
     2016-01-05  17.190001  17.530001  17.059999  17.450001  417500  17.162061,
     'CLSN':             Open  High   Low  Close  Volume  Adj Close
     Date
     2015-12-31  1.92  1.99  1.87   1.92   79600       1.92
     2016-01-04  1.93  1.99  1.87   1.93   39700       1.93
     2016-01-05  1.89  1.94  1.85   1.90   50200       1.90}
    

    解决方案:

    In [73]: pd.Panel(d2).swapaxes(0, 2).to_frame().reset_index(level=0).sort_index()
    Out[73]:
                Date       Open       High        Low      Close    Volume  Adj Close
    minor
    CCC   2015-12-31  17.270000  17.389999  17.120001  17.250000  177200.0  16.965361
    CCC   2016-01-04  17.000000  17.219999  16.600000  17.180000  371600.0  16.896516
    CCC   2016-01-05  17.190001  17.530001  17.059999  17.450001  417500.0  17.162061
    CLSN  2015-12-31   1.920000   1.990000   1.870000   1.920000   79600.0   1.920000
    CLSN  2016-01-04   1.930000   1.990000   1.870000   1.930000   39700.0   1.930000
    CLSN  2016-01-05   1.890000   1.940000   1.850000   1.900000   50200.0   1.900000
    

    或者,您可以将 Date 作为索引的一部分:

    In [74]: pd.Panel(d2).swapaxes(0, 2).to_frame().sort_index()
    Out[74]:
                           Open       High        Low      Close    Volume  Adj Close
    Date       minor
    2015-12-31 CCC    17.270000  17.389999  17.120001  17.250000  177200.0  16.965361
               CLSN    1.920000   1.990000   1.870000   1.920000   79600.0   1.920000
    2016-01-04 CCC    17.000000  17.219999  16.600000  17.180000  371600.0  16.896516
               CLSN    1.930000   1.990000   1.870000   1.930000   39700.0   1.930000
    2016-01-05 CCC    17.190001  17.530001  17.059999  17.450001  417500.0  17.162061
               CLSN    1.890000   1.940000   1.850000   1.900000   50200.0   1.900000
    

    旧答案 - 它假定 Date 是常规列(不是索引) 试试这个:

    In [59]: pd.Panel(d).swapaxes(0, 2).to_frame().reset_index('major', drop=True).sort_index()
    Out[59]:
                Date   Open   High    Low  Close  Volume Adj Close
    minor
    CCC   2015-12-31  17.27  17.39  17.12  17.25  177200   16.9654
    CCC   2016-01-04     17  17.22   16.6  17.18  371600   16.8965
    CCC   2016-01-05  17.19  17.53  17.06  17.45  417500   17.1621
    CLSN  2015-12-31   1.92   1.99   1.87   1.92   79600      1.92
    CLSN  2016-01-04   1.93   1.99   1.87   1.93   39700      1.93
    CLSN  2016-01-05   1.89   1.94   1.85    1.9   50200       1.9
    

    d 是你的nested dictionary

    In [60]: d
    Out[60]:
    {'CCC':         Date       Open       High        Low      Close  Volume  Adj Close
     0 2015-12-31  17.270000  17.389999  17.120001  17.250000  177200  16.965361
     1 2016-01-04  17.000000  17.219999  16.600000  17.180000  371600  16.896516
     2 2016-01-05  17.190001  17.530001  17.059999  17.450001  417500  17.162061,
     'CLSN':         Date  Open  High   Low  Close  Volume  Adj Close
     0 2015-12-31  1.92  1.99  1.87   1.92   79600       1.92
     1 2016-01-04  1.93  1.99  1.87   1.93   39700       1.93
     2 2016-01-05  1.89  1.94  1.85   1.90   50200       1.90}
    

    【讨论】:

    • 我已经按照你说的做了,但是它返回一个错误:KeyError: 'Level major not found',我几乎不明白你的代码是什么意思,swapaxes(0, 2),而且我似乎没有@的定义987654334@.
    • @PanKevin,您也可以改用reset_index(level=0, drop=True)。但这很奇怪,因为我希望在完成 reset_index() 之后会有一个 major 列...
    • 太棒了!它的所有输出都很小,但是缺少日期列..就像minor Open High Low Close Volume Adj Close A 41.900002 42.349998 41.720001 41.810001 1449300.0 41.357005 A 37.369999 37.950001 37.000000 37.689999 2666200.0 37.281641 A 37.400002 38.029999 37.400002 37.610001 1831200.0 37.202510 A 40.240002 40.990002 40.049999 40.730000 2103600.0 40.288705,你能解释一下吗??
    • @PanKevin,你能post in your question 输出print(nas['CLSN'].head()) 吗?您的 Date 列是否可能是字典中原始 DF 中的索引?
    • 我已经发布了,我完全同意 Date 列是 DF 的索引。在我发布问题之前,我对输出进行了一些编辑,如果这让你感到困惑,我真的很抱歉......
    【解决方案2】:

    也许 pandas.concat 就是你要找的东西:

    In [8]: data = dict(A=pd.DataFrame([[1,2], [3,4]], columns=['X', 'Y']),
                        B=pd.DataFrame([[1,2], [3,4]], columns=['X', 'Y']),)
    
    In [9]: data
    Out[9]: 
    {'A':    X  Y
     0  1  2
     1  3  4, 
     'B':    X  Y
     0  1  2
     1  3  4}
    
    In [10]: pd.concat(data)
    Out[10]: 
         X  Y
    A 0  1  2
      1  3  4
    B 0  1  2
      1  3  4
    

    【讨论】:

    • 谢谢,但是 Python 运行时间太长,无法输出结果。我用这个:df = pd.concat(pd.Panel(nas)[k] for k in nas.keys()) ,它一直在运行。
    猜你喜欢
    • 2021-08-30
    • 2019-09-06
    • 2014-05-10
    • 1970-01-01
    • 2021-11-28
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多