【问题标题】:Pandas dataframe from dictionary of list values来自列表值字典的 Pandas 数据框
【发布时间】:2018-11-17 22:57:26
【问题描述】:

我有一本字典,其中包含以下值:

cols = {'animals':['dog','cat','fish'],
        'colors':['red','black','blue','dog']}

我想将其转换为一个数据框,其中每个列表都根据它们的键进行枚举,结果为

key variable
animals dog
animals cat
animal fish
colors red
colors black
colors blue
colors dog

到目前为止,我已经这样做了:但它没有为我提供想要的结果。

cols_df = pd.DataFrame.from_dict(cols, orient='index')

如何修改它以实现上述目标?

【问题讨论】:

  • 你想要长格式,但from_dict(.. orient='index') 只提供宽格式,from_dict(.. orient='columns') 失败并显示ValueError('arrays must all be same length')

标签: python list pandas dictionary dataframe


【解决方案1】:

无导入,适用于所有输入:

>>> pd.DataFrame([(key, var) for (key, L) in cols.items() for var in L], 
                 columns=['key', 'variable'])

       key variable
0  animals      dog
1  animals      cat
2  animals     fish
3   colors      red
4   colors    black
5   colors     blue
6   colors      dog

【讨论】:

    【解决方案2】:

    这可能不是最快的解决方案,您需要额外的列表。

    d = {'animals': ['dog','cat','fish'],
         'colors': ['red','black','blue','dog']}
    
    keys = [k for k in d.keys() for v in d[k]]
    values = [v for k in d.keys() for v in d[k]]
    pd.DataFrame.from_dict({'index': keys, 'values': values})
    

    【讨论】:

      【解决方案3】:
      pd.DataFrame.from_dict(cols, orient='index').T.unstack().dropna().reset_index(level=1,drop=True)
      
      animals      dog
      animals      cat
      animals     fish
      colors       red
      colors     black
      colors      blue
      colors       dog
      

      我们首先需要将 cols 填充到相等的长度以防止 from_dict(.. orient='columns') 失败。两种方法:

      1. pd.DataFrame.from_dict(cols, orient='index').T 是我在 this answer by root 中发现的一个未记录的技巧; transpose 添加 NaN 单元格以使结果为矩形
      2. 手动替代方法是找出每行需要填充多少个单元格,例如:

        df_cols.apply(pd.Series.pad, max(len(c) for c in cols.values())) ... cols['animals'].append(np.NaN)计算填充量

      【讨论】:

        【解决方案4】:

        你可以使用stack:

        df = pd.DataFrame.from_dict(cols, orient='index')
        df = df.stack().to_frame().reset_index().drop('level_1', axis=1)
        df.columns = ['key', 'variable']
        
        df
        
        key variable
        0   colors  red
        1   colors  black
        2   colors  blue
        3   colors  dog
        4   animals dog
        5   animals cat
        6   animals fish
        

        演示:

        df = pd.DataFrame.from_dict(cols, orient='index')
        df
        
                0   1      2    3
        colors  red black  blue dog
        animals dog cat    fish None
        

        df.stack() 返回一个系列。这需要使用to_frame() 转换为数据帧。之后执行reset_index() 以获得所需的帧。

        df.stack().to_frame().reset_index()
        
        
         level_0 level_1 0
        0   colors  0   red
        1   colors  1   black
        2   colors  2   blue
        3   colors  3   dog
        4   animals 0   dog
        5   animals 1   cat
        6   animals 2   fish
        

        现在drop('level_1', axis=1) 并设置列名得到预期的帧。

        【讨论】:

          【解决方案5】:

          使用itertools.chainitertools.repeat

          import pandas as pd
          from itertools import chain, repeat
          
          chainer = chain.from_iterable
          
          d = {'animals': ['dog', 'cat', 'fish'],
               'colors': ['red', 'black', 'blue', 'dog']}
          
          df = pd.DataFrame({'key': list(chainer(repeat(k, len(v)) for k, v in d.items())),
                             'variable': list(chainer(d.values()))})
          
          print(df)
          
                 key variable
          0  animals      dog
          1  animals      cat
          2  animals     fish
          3   colors      red
          4   colors    black
          5   colors     blue
          6   colors      dog
          

          【讨论】:

            【解决方案6】:

            使用 itertools crossproduct 创建可以加载到数据帧中的键/值配对字典

             import itertools
            
             cols = {'animals':['dog','cat','fish'],
                'colors':['red','black','blue','dog']}
            
             keys=cols.keys()
             values=cols.values()
            
             data=[]
             for key,values in cols.items():
                 results=itertools.product([key],values)
                 for key,item in enumerate(results):
                      data.append(item)
            
             df=pd.DataFrame(data,columns=['category','value'])
             print(df)
            

            输出:

              category  value
            0  animals    dog
            1  animals    cat
            2  animals   fish
            3   colors    red
            4   colors  black
            5   colors   blue
            6   colors    dog
            

            【讨论】:

              猜你喜欢
              • 2018-05-04
              • 2016-02-10
              • 2014-09-28
              • 2019-02-23
              • 2021-09-03
              • 1970-01-01
              • 1970-01-01
              • 2015-05-30
              • 1970-01-01
              相关资源
              最近更新 更多