【问题标题】:dataframe from dictionary of dictionary in list列表中字典字典中的数据框
【发布时间】:2020-02-04 22:38:17
【问题描述】:

我有一个这样的字典列表:

my_list = [
    {
        'Currency': 'USD',
        'Product': 'a',
        'Quantity': {
            'Apr 2019': 1.0,
            'Jun 2019': 7.0
        }
    },
    {
        'Currency': 'USD',
        'Product': 'b',
        'Quantity': {
            'Jan 2019': 4.0,
            'Feb 2019': 8.0
        }
    }
]

我想要一个这样的数据框:

 Currency Product Quantity  Date
 'USD'      'a'      1      Apr 2019
 'USD'      'a'      7      Jun 2019
 'USD'      'b'      4      Jan 2019
 'USD'      'b'      8      Feb 2019

目前我正在这样做:

for element in my_list :
     currency = element.get('Currency')
     product = element.get('Product')
     dates = list(element.get('Quantity').keys())
     for date in dates:
         quantity = element.get('Quantity')[date]
         row = [currency, product, quantity, date]
         df.loc[df.shape[0]] = row

但我想有一种更好的方法来代替列表中的循环和

pd.DataFrame.from_dict(my_list)

如果数量只有一个值,则有效(使用 .apply 稍作修改)

谢谢

【问题讨论】:

    标签: python pandas list dataframe dictionary


    【解决方案1】:
    df_dict = [{**d, "Quantity": quantity, "Date": date,} for d in my_list for date, quantity in d['Quantity'].items()]
    
    df = pd.DataFrame.from_dict(df_dict)
    

    输出

    >>> df
    
    Currency    Product Quantity    Date
    0   USD         a       1.0         Apr 2019
    1   USD         a       7.0         Jun 2019
    2   USD         b       4.0         Jan 2019
    3   USD         b       8.0         Feb 2019
    

    解释

    通过使用双嵌套循环,您可以通过数量/日期对的数量来枚举您的列表 - 这正是您想要的。然后在第一层解压字典(使用**d)。这设置了正确的 CurrencyProduct 值,但给我们留下了“坏”的 Quantity 值。这在字典理解的下一步中被覆盖。最后,设置了Date。从那里开始,熊猫将每个字典作为一行读取。

    【讨论】:

    • ok thnaks,它适用于这个例子我的数据是完全不同的,实际上字典中有两个字典(一个是数量和日期,一个是值和日期(日期是相同))我可以调整您的解决方案(尤其是日期,数量在 d['Quantity'].items() 中的部分)吗?
    • 好的,我有与上面相同的过程:"Value": d.get('Value')[date] in your dictionary
    • @kilag 嗯,我并没有完全想象你在描述什么。你能寄给我一个示例字典吗?无论哪种方式,我的猜测是,如果有更多的东西需要解压,我的解决方案就不应该使用。一旦您必须解压 3 个或更多嵌套字典,这将成为一个非常混乱的解决方案。
    • 我的对象是这样的:my_list = [ { 'Currency': 'USD', 'Product': 'a', 'Quantity': { 'Apr 2019': 1.0, 'Jun 2019' : 7.0 }, 'Value': { 'Apr 2019': 10.4, 'Jun 2019': 72.1 } }, { 'Currency': 'USD', 'Product': 'b', 'Quantity': { 'Jan 2019 ': 4.0, 'Feb 2019': 8.0 }, 'Value': { 'Jan 2019': 1.45, 'Feb 2019': 2.98 } } ] 所以通过添加“Value”:d.get('Value')[date ] 它有效
    【解决方案2】:

    您可以使用双循环来处理您的数据。

    以下代码

    df = pd.DataFrame(
        [
            {
                'Currency': item.get('Currency'),
                'Product': item.get('Product'),
                'Date': quant_key,
                'Quantity': quant_val,
            } for item in my_list for quant_key, quant_val in item['Quantity'].items()
        ]
    )
    print(df)
    

    返回这个输出:

      Currency Product      Date  Quantity
    0      USD       a  Apr 2019       1.0
    1      USD       a  Jun 2019       7.0
    2      USD       b  Jan 2019       4.0
    3      USD       b  Feb 2019       8.0
    

    【讨论】:

    • 谢谢,我会保留这个稍作修改,我在循环中添加 'Value': item.get('Value')[quant_key] 以添加来自其他字典的值跨度>
    【解决方案3】:

    使用json_normalize:

    from pandas.io.json import json_normalize
    df=json_normalize(my_list,'Quantity',['Currency','Product'])
    Quantity=[]
    for d in my_list:
        for month in  d['Quantity']:
            Quantity.append(d['Quantity'][month])
    df['Quantity']=Quantity
    df=df.rename(columns={0:'Date'}).reindex(columns=['Currency','Product','Quantity','Date'])
    print(df)
    
    
      Currency Product  Quantity      Date
    0      USD       a       1.0  Apr 2019
    1      USD       a       7.0  Jun 2019
    2      USD       b       4.0  Jan 2019
    3      USD       b       8.0  Feb 2019
    

    【讨论】:

      猜你喜欢
      • 2020-12-28
      • 2018-05-03
      • 2021-08-14
      • 2022-12-05
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2021-04-10
      相关资源
      最近更新 更多