【问题标题】:pd.melt() a dictionary/series of dataframespd.melt() 一个字典/一系列数据帧
【发布时间】:2021-04-09 07:49:12
【问题描述】:

例如我有以下地图:

  {'df1': Jan    Feb    Mar
           1      3      5
           2      4      6
   'df2': Jan    Feb    Mar
           7      9      11
           8      10     12
    ......}

我想要以下输出:

Jan  1
Jan  2
Feb  3
Feb  4
Mar  5
Mar  6
Jan  7
Jan  8
Feb  9
Feb  10
Mar  11
Mar  12

有谁知道这样做是否可行? 我尝试的是遍历 DataFrames 以尝试获取

  {'df1': Jan  1
          Jan  2
          Feb  3
          Feb  4
          Mar  5
          Mar  6

   'df2': Jan  7
          Jan  8
          Feb  9
          Feb  10
          Mar  11
          Mar  12

通过使用

for x in dfMap:
    df = pd.melt(list(x.values()))

然后尝试用 df1m = 连接它

pd.concat(df.values(), ignore_index=True)

这给了我错误

AttributeError: 'list' object has no attribute 'columns'

我对编程还很陌生,真的很想学习,如果有人能解释这是如何工作的,以及为什么 list 或 dict_values 对象没有属性“columns”,那就太好了。

提前致谢!

【问题讨论】:

    标签: python excel pandas dataframe dictionary


    【解决方案1】:

    你可以连接和堆叠:

    out = pd.concat(d.values()).stack().droplevel(0)
    

    或者:

    out = pd.concat(d.values()).melt()
    

    例子:

    df = pd.DataFrame(np.arange(1,10).reshape(-1,3),columns=['Jan','Feb','Mar'])
    d = {}
    for e,i in df.iterrows():
        d[f"df{e+1}"] = i.to_frame().T
    print(d,'\n')
    
    out = pd.concat(d.values()).stack().droplevel(0)
    print(out)
    

        {'df1':    Jan  Feb  Mar
    0    1    2    3, 'df2':    Jan  Feb  Mar
    1    4    5    6, 'df3':    Jan  Feb  Mar
    2    7    8    9} 
    
    Jan    1
    Feb    2
    Mar    3
    Jan    4
    Feb    5
    Mar    6
    Jan    7
    Feb    8
    Mar    9
    dtype: int32
    

    melt:

    out = pd.concat(d.values()).melt()
    print(out)
    
      variable  value
    0      Jan      1
    1      Jan      4
    2      Jan      7
    3      Feb      2
    4      Feb      5
    5      Feb      8
    6      Mar      3
    7      Mar      6
    8      Mar      9
    

    编辑,对于已编辑的问题,请尝试:

    out = pd.concat(d).stack().sort_index(level=[0,-1]).droplevel([0,1])
    

    下面的例子:

    df = pd.DataFrame(np.arange(1,13).reshape(3,-1).T,columns=['Jan','Feb','Mar'])
    d = {}
    for e,i in df.groupby(df.index//2):
        d[f"df{e+1}"] = i
    print(d,'\n')
    
    out = pd.concat(d).stack().sort_index(level=[0,-1]).droplevel([0,1])
    print(out)
    
    {'df1':    Jan  Feb  Mar
    0    1    5    9
    1    2    6   10, 'df2':    Jan  Feb  Mar
    2    3    7   11
    3    4    8   12} 
    
    Jan     1
    Jan     2
    Feb     5
    Feb     6
    Mar     9
    Mar    10
    Jan     3
    Jan     4
    Feb     7
    Feb     8
    Mar    11
    Mar    12
    dtype: int32
    

    或者您也可以将数据框名称转换为 int 然后排序:

    out = (pd.concat(d.values(),keys=[int(key[2:]) for key in d.keys()])
       .stack().sort_index(level=[0,-1]).droplevel([0,1]))
    

    【讨论】:

    • 谢谢,它有效,但我确实需要向你道歉,显然我在提问时犯了一些错误。我相信这只是逻辑问题,对吗?输出必须看起来像这样的原因是因为它将进一步更改为 DateTime 而不是月份。
    • @user14783839 编辑了我的答案,查看编辑部分
    • 我实际上使用以下代码来获取字典,( dfMap = {} for sheet_name in xls.sheet_names: dfMap[sheet_name] = xls.parse(sheet_name, header=4, usecols='C :N', skiprows= range(35,45), engine= 'openpyxl') ) 导致键名格式为 "dict_keys(['1994_x0009__x0009_', '1995_x0009_', '1996_x0009_',..." 和错误ValueError: int() 以 10 为底的无效文字:'',这是我认为正确的 dict_keys 格式引起的?
    • pd.concat 内尝试keys = [int(key.split("_")[0]) for key in dfMap.keys()]? @user14783839
    • @user14783839 如果上述方法不起作用:您可以创建一个包含所有必要详细信息的单独问题,以便我或其他贡献者可以查看并尝试回答该问题。由于您提供的密钥为 'df1''df2'
    猜你喜欢
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2020-02-18
    • 2017-05-18
    相关资源
    最近更新 更多