【问题标题】:Extract value from a dataframe column of dictionary of lists lists and create a new column从列表字典的数据框列中提取值并创建一个新列
【发布时间】:2022-11-30 22:55:13
【问题描述】:

我有一个数据框,其中一列作为列表,另一列作为字典。然而,这并不一致。它可以是单个元素,也可以是 NULL

df = pd.DataFrame({'item_id':[1,1,1,2,3,4,4],
'shop_id':['S1','S2','S3','S2','S3','S1','S2'], 
'price_list':[{'10':['S1','S2'], '20':['S3'], '30':['S4']},{'10':['S1','S2'], '20':['S3'], '30':['S4']},{'10':['S1','S2'], '20':['S3'], '30':['S4']},'50','NaN',{'10':['S1','S2','S3'],'25':['S4']},{'10':['S1','S2','S3'],'25':['S4']}]})


+---------+---------+--------------------------------------------------+
| item_id | shop_id |                      price_list                  |
+---------+---------+--------------------------------------------------+
|       1 | S1      | {'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']} |
|       1 | S2      | {'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']} |
|       1 | S3      | {'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']} |
|       2 | S2      | 50                                               |
|       3 | S3      | NaN                                              |
|       4 | S1      | {'10': ['S1', 'S2', 'S3'], '25': ['S4']}         |
|       4 | S2      | {'10': ['S1', 'S2', 'S3'], '25': ['S4']}         |
+---------+---------+--------------------------------------------------+

我希望将其扩展为:

+---------+---------+-------+
| item_id | shop_id | price |
+---------+---------+-------+
|       1 | S1      | 10    |
|       1 | S2      | 10    |
|       1 | S3      | 20    |
|       2 | S2      | 50    |
|       3 | S3      | NaN   |
|       4 | S1      | 10    |
|       4 | S2      | 10    |
+---------+---------+-------+

我试过 apply :

def get_price(row):
    if row['price_list'][0]=='{':
        prices = eval(row['price_list'])
        for key,value in prices.items():
            if str(row['shop_id']) in value:
                price = key
                break
            price =  np.nan
    else:
        price =  row["price_list"]
    return price


df['price'] = df.apply(lambda row: get_price(row),axis=1)

但是由于我的数据框非常大,因此上述方法需要花费很多时间。

实现这一目标的最佳方法是什么?任何建议表示赞赏。谢谢!

【问题讨论】:

    标签: python pandas dataframe dictionary list-comprehension


    【解决方案1】:

    我不知道这是否是最好的方法。至少,它有效。

    df['price'] = df.apply(lambda x: [k for k,v in x['price_list'].items() if x['shop_id'] in v][0] if type(x['price_list'])==dict else x['price_list'], axis=1)
    df.drop('price_list', axis=1, inplace=True)
    

    输出:

       item_id shop_id price
    0        1      S1    10
    1        1      S2    10
    2        1      S3    20
    3        2      S2    50
    4        3      S3   NaN
    5        4      S1    10
    6        4      S2    10
    

    【讨论】:

      【解决方案2】:

      我会使用带有生成器的列表理解来从值中搜索键:

      df['price'] = [next((k for k,l in d.items() for v in l if v==s), None)
                     if isinstance(d, dict) else d
                     for s, d in zip(df['shop_id'], df.pop('price_list'))]
      

      注意。 pop 删除了“price_list”列。

      输出:

         item_id shop_id price
      0        1      S1    10
      1        1      S2    10
      2        1      S3    20
      3        2      S2    50
      4        3      S3   NaN
      5        4      S1    10
      6        4      S2    10
      

      【讨论】:

        猜你喜欢
        • 2020-09-05
        • 2022-01-16
        • 2019-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多