【问题标题】:how to split dictionary to separate rows in pandas如何拆分字典以分隔熊猫中的行
【发布时间】:2020-06-12 11:45:14
【问题描述】:

我有一个这样的数据框:

  | col1 | d
-------------------------------------------
0 | A    | {'student99': [[0.83, "nice"]]}
1 | B    | {'student99': [[0.84, "great"], [0.89, "cool"]]}
2 | C    | {'student98': [[0.85, "amazing"]], 'student97': [[0.9, "crazy"]]}

我正在尝试转换为如下数据框:

  | col1 | student  | grade | comment
---------------------------------------------
0 | A    | student99| 0.83  | nice
1 | B    | student99| 0.84  | great
2 | B    | student99| 0.89  | cool 
3 | C    | student98| 0.85  | amazing 
4 | C    | student97| 0.9   | crazy

如您所见,我需要将 d 列拆分为 student 、 grade 和 comment 列,并且我需要根据 d 列中的键数将行拆分为一些行(如上面的 C 行)和每个键的列表数(如上面的 B 行)。

我该怎么做?

在评论之后,我注意到数据以 JSON 格式以下一种格式到达(我将其转换为数据框):

{"A": {"d" : {'student99': [[0.83, "nice"]]}}, 
 "B": {"d" : {'student99': [[0.84, "great"], [0.89, "cool"]]},
 "C": {"d" : {'student98': [[0.85, "amazing"]], 'student97': [[0.9, "crazy"]]}
}

【问题讨论】:

  • 您从哪里获得数据?也许在上游修复它会更容易。
  • 我得到它作为 json 文件。我会在上面附上他的结构。

标签: python pandas dictionary


【解决方案1】:

我们可以用pd.Series 做explode 然后重新创建数据框join 它回来

s=df.pop('d').apply(pd.Series).stack().explode()
df_add=pd.DataFrame({'student':s.index.get_level_values(1),
                      'grade':s.str[0].values,
                      'comment':s.str[1].values},
                     index=s.index.get_level_values(0))
df=df.join(df_add,how='right')
df
Out[169]: 
    col1    student  grade  comment
0  A      student99   0.83     nice
1  B      student99   0.84    great
1  B      student99   0.89     cool
2  C      student98   0.85  amazing
2  C      student97   0.90    crazy

【讨论】:

    【解决方案2】:

    @YOBEN_S 的解决方案很棒;这是对更快解决方案的尝试:

    from itertools import product, chain
    
    #chain.... is long... flatten is shorter
    #and still gets the point accross
    flatten = chain.from_iterable
    
    #flatten the product of each key,value pair 
    #in the dictionary
    m = [(first, flatten(product([key], value) for key, value in last.items()))
         for first, last in emp]
    
    #flatten again
    phase2 = flatten(product(first, last) for first, last in m)
    
    #at this point we have 
    #the column entry("A","B",...)
    #and the flattened entries in the dict
    #so, unpacking solves this
    phase3 = [(first,second, *last) for first, (second,last) in phase2]
    
    result = pd.DataFrame(phase3, columns = ["col1","student","grade","comment"])
    
    result
    
    
        col1    student grade   comment
    0   A   student99   0.83    nice
    1   B   student99   0.84    great
    2   B   student99   0.89    cool
    3   C   student98   0.85    amazing
    4   C   student97   0.90    crazy
    

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 2021-07-02
      • 2023-03-21
      • 2019-05-17
      • 2020-12-26
      • 2017-11-27
      • 2019-05-27
      相关资源
      最近更新 更多