【问题标题】:Creating a dataframe from a dict where keys are tuples从键是元组的字典创建数据框
【发布时间】:2017-10-16 03:55:13
【问题描述】:

我有以下字典,键为元组:

d = {('first', 'row'): 3, ('second', 'row'): 1}

我想创建一个包含 3 列的数据框:Col1、Col2 和 Col3,它们应该如下所示:

Col1   Col2  Col3
first  row   3
second row   4

除了逐对解析字典之外,我不知道如何拆分元组。

【问题讨论】:

  • 我建议你接受@ayhan 的回答——它更优雅!
  • 完成。老实说,一开始我并没有完全理解它,但我同意:它更优雅

标签: python pandas


【解决方案1】:

您可以轻松地从dict 创建一个数据框:

import pandas as pd

d = {('first', 'row'): 3, ('second', 'row'): 1}

df = pd.DataFrame.from_dict({'col': d}, orient='columns')

df

        |     | col |
 ------ | --- | --- |
 first  | row |   3 |
 second | row |   1 |

现在出于美观目的,您可以通过以下方式获取输出数据框:

df = df.reset_index()
df.columns = 'Col1 Col2 Col3'.split()

【讨论】:

    【解决方案2】:

    先构造一个Series,然后重置索引会给你一个DataFrame:

    pd.Series(d).reset_index()
    Out: 
      level_0 level_1  0
    0   first     row  3
    1  second     row  1
    

    您可以在之后重命名列:

    df = pd.Series(d).reset_index()   
    df.columns = ['Col1', 'Col2', 'Col3']   
    df
    Out: 
         Col1 Col2  Col3
    0   first  row     3
    1  second  row     1
    

    或者在一行中,先命名MultiIndex:

    pd.Series(d).rename_axis(['Col1', 'Col2']).reset_index(name='Col3')
    Out[7]: 
         Col1 Col2  Col3
    0   first  row     3
    1  second  row     1
    

    【讨论】:

    • 这很有趣!我不知道我们可以直接从这样的字典创建系列......
    • 我不知道系列可以成为数据框......我想我有一些文档要阅读。
    • @pshep123 是的,通常您可以使用ser.to_frame('name_of_the_column) 将Series 转换为单列DataFrame。 reset_index 默认情况下将索引转换为列,因为一个系列不能有超过一列,它也转换为一个数据帧。
    • 这是一个很好的答案。我尝试将它直接传递给数据框,但没有得到预期的解决方案。 pd.DataFrame.from_dict(d,orient="index").reset_index() 没有直接工作。
    【解决方案3】:

    我很好奇是否可以使用 MultiIndexes,所以我尝试了一下。如果您想指定级别,这可能有其好处。但只是按照 pandas 文档示例 (MultiIdex) 我想出了一个替代解决方案。

    首先我创建了一个随机数据字典

    s = {(1,2):"a", (4,5):"b", (1,5):"w", (2, 3):"z", (4,1):"p"}
    

    然后我使用pd.MultiIndex 根据字典的键创建层次索引。

    index = pd.MultiIndex.from_tuples(s.keys())
    
    
    index
    Out[3]: 
    MultiIndex(levels=[[1, 2, 4], [1, 2, 3, 5]],
            labels=[[0, 2, 2, 1, 0], [1, 3, 0, 2, 3]])
    

    然后,我将字典的值直接传递给 pandas Series,并将索引显式设置为我在上面创建的 MultiIndex 对象。

    pd.Series(s.values(), index=index)
    Out[4]: 
    1  2    a
    4  5    b
       1    p
    2  3    z
    1  5    w
    dtype: object
    

    最后,我重置了索引以获得 OP 请求的解决方案

    pd.Series(s.values(), index=index).reset_index()
    Out[5]: 
    level_0  level_1  0
    0        1        2  a
    1        4        5  b
    2        4        1  p
    3        2        3  z
    4        1        5  w
    

    这涉及更多,因此@ayhan 的回答可能仍然更可取,但我认为这让您了解熊猫可能在后台做什么。或者至少让任何人有机会更多地修改 pandas 的机制。

    【讨论】:

      【解决方案4】:

      不像@ayhan 的解决方案那么优雅:

      In [21]: pd.DataFrame(list(d), columns=['Col1','Col2']).assign(Col3=d.values())
      Out[21]:
           Col1 Col2  Col3
      0   first  row     3
      1  second  row     1
      

      或者一个简单的:

      In [27]: pd.DataFrame([[k[0],k[1],v] for k,v in d.items()]) \
                 .rename(columns={0:'Col1',1:'Col2',2:'Col2'})
      Out[27]:
           Col1  Col2  Col2
      0   first   row     3
      1  second   row     1
      

      【讨论】:

        猜你喜欢
        • 2020-03-21
        • 2017-04-30
        • 2021-04-03
        • 2017-05-07
        • 2016-10-22
        • 1970-01-01
        • 2020-01-05
        • 2021-12-30
        • 2018-09-21
        相关资源
        最近更新 更多